WPF DisplayMemberPath仅在嵌套视图/ VM时启动时工作

时间:2017-10-07 22:04:47

标签: c# wpf xaml listbox user-controls

我有一个失败的DisplayMemberPath值。

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

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

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

这是功能代码。请注意我已将其简化为此问题的目的。您可以忽略命名约定等。

这是usercontrol。它是一个包含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>

这是我的MainWindo视图,它接收UserControl:

<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(usercontrol实际上是我为此问题简化的更复杂的子视图的一部分)在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");
        }
    }
}

1 个答案:

答案 0 :(得分:2)

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