2017-10-07 8 views
1

DisplayMemberPathの値に問題があります。WPF DisplayMemberPathは、ビュー/ VMの入れ子になると起動時にのみ動作します

私のプロジェクトのセットアップでは、ChildView(この子ビューはこの質問のために失敗した単一のコントロールに簡略化しています)を含むParentViewを持っています。親ビューのDataContextはVM内の親VMに設定され、DataTemplateはChildViewのコンテキストを設定するために使用されます。そのDataTemplateは親ビューに設定されます。

問題:ListBoxのFileInfoオブジェクトのFullFileNameプロパティ値ではなく、FileNameを表示する必要があります。 DisplayMemberNameを設定しました。これは、ChildView/UserControlでバインディングとして設定したときに部分的に機能します。それは、アプリケーションの起動時にのみ機能します。 FileInfoオブジェクトをChildVMに追加すると、ListBoxに表示されますが、FileNameとして表示されません。代わりに、私はFullFileNameを取得します。

私はバインディングをトリガーするイベントがないことには理由がありますが、最初はこの方法でバインドするべきではないと私は完全にはわかりません。

これは機能コードです。私はこの質問の目的のために簡略化していることに注意してください。命名規則などは無視してもかまいません。

ここにusercontrolがあります。これは、DisplayMemberNameをFileInfo.FileName値に設定したいFileInfoオブジェクトを含むリストボックスです。

<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ビューです:

<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> 

これは、ユーザーコントロールのためのVM(ユーザーコントロールは、実際に私はこのquesitonのために簡略化されているより複雑な子ビューの一部です)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"); 
     } 
    } 
} 

答えて

2

それはDisplayMemberPath="Name"と思いませんか?実際の "FileName"プロパティは表示されません。 NameFullNameがあります。

+1

どのように私はとても愚かなことができます... :( –

+0

私は感じを知っています。十分に長くコードを見て、物事を見始める。 – Laith

関連する問題