WPF DisplayMemberPath 仅在嵌套时启动时有效 Views/VMs

WPF DisplayMemberPath Only Works On Launch When Nesting Views/VMs

我有一个失败的 DisplayMemberPath 值。

我的项目的设置是我有一个包含 ChildView 的 ParentView(这个子视图我已经简化为这个问题失败的单个控件)。 Parent view的DataContext在VM中设置一个Parent VM,一个DataTemplate用于设置ChildView的context。该 DataTemplate 在父视图中设置。

问题:我需要显示 FileName,而不是 ListBox 中 FileInfo 对象的 FullFileName 属性 值。我已经设置了 DisplayMemberName,当我在 ChildView/UserControl 中设置为绑定时,它部分起作用。也就是说它只适用于应用程序的启动。如果我将 FileInfo 对象添加到我的 ChildVM - 它会显示在列表框中,但不会显示为 FileName。相反,我只是得到 FullFileName。

按理说我错过了触发绑定的事件,但我不完全确定我应该首先以这种方式绑定。

这是功能代码。请注意,出于这个问题的目的,我已经简化了它。您可以忽略命名约定等。

这是用户控件。它是一个包含 FileInfo 对象的列表框,我想为其设置 DisplayMemberName 为 FileInfo.FileName 值。

<UserControl x:Class="CatalogInterface.ctlDirFilesListBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:CatalogInterface"
             xmlns:vm="clr-namespace:CatalogInterface.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <Grid x:Name="MainControlGrid">
        <ListBox x:Name="FileListBox" 
                 DisplayMemberPath="{Binding ElementName=Files, Path=Files.FileName}"
                 <!-- Also tried DisplayMemberPath="FileName" -->
                 ItemsSource="{Binding Files}"
                 SelectedItem="{Binding Path=SelectedFiles}"
                 SelectionChanged="ListBoxItem_SelectionChanged" 
                 HorizontalAlignment="Stretch" 
                 VerticalAlignment="Stretch" 
                 Background="#FFFFFF"
                 Grid.Row="2" 
                 Grid.Column="1" 
                 Grid.ColumnSpan="3" 
                 BorderThickness="0">
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
                    <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
                    <EventSetter Event="KeyDown" Handler="ListBoxItem_KeyDown"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>
</UserControl>

这是我的包含 UserControl 的 MainWindo 视图:

<Window x:Name="FCTWindow" x:Class="CatalogInterface.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CatalogInterface"
        xmlns:vm="clr-namespace:CatalogInterface.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="532">

    <Window.DataContext>
        <vm:MainWindowViewModel />
    </Window.DataContext>

    <!--#region Body Left Side Grid-->
    <Grid x:Name="BodyGridLeft" Grid.Row="0" Grid.Column="0">
        <UserControl Content="{Binding DirFilesViewModel}">
            <UserControl.ContentTemplate>
                <DataTemplate>
                    <local:ctlDirFilesListBox />
                </DataTemplate>
            </UserControl.ContentTemplate>
        </UserControl>
    </Grid>
    <!--#endregion Body Left Side-->
</Window>

这是 UserControl 的 VM(用户控件实际上是我为此问题简化的更复杂的子视图的一部分)在 VM 中,当调用 OnPublishDirFiles() 时更新列表框:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;

namespace CatalogInterface.ViewModels
{
    public class DirFilesViewModel : ViewModelBase<DirFilesModel>
    {
        private object _selectedFiles;
        private Messenger _messenger;

        public object SelectedFiles
        {
            get { return _selectedFiles; }
            set {
                SetProperty<object>(ref _selectedFiles, value);
                _messenger.SendMessage(this, "DirFilesListBox_SelectedDocumentChanged", _selectedFiles);
            }
        }

        public ObservableCollection<FileInfo> Files { get; set; }
        private DirFilesModel _model;

        public DirFilesViewModel()
        {
            _model = new DirFilesModel();
            Files = new ObservableCollection<FileInfo>();
            this.OnPublishDirFiles(this, new MessageEventArgs("s", "o"));
            _messenger = Messenger.Set_Messenger();
            _messenger.Register(OnPublishDirFiles, "PublishDirFiles");
        }
        protected virtual void OnPublishDirFiles(object source, MessageEventArgs e)
        {
            PublishDirFiles();
        }
        private void PublishDirFiles()
        {
            if (Files == null) { } //raise NullArgumentException
            Files.Clear();
            foreach (FileInfo f in _model.Files) Files.Add(f);
            OnPropertyChanged("Files.FileName");
        }
    }
}

不就是DisplayMemberPath="Name"吗?我没有看到实际的 "FileName" 属性。有 NameFullName