2017-10-07 10 views
1

J'ai une valeur DisplayMemberPath qui échoue.WPF DisplayMemberPath ne fonctionne qu'au démarrage lors de l'imbrication de vues/machines virtuelles

La mise en place de mon projet est que j'ai un ParentView qui contient un ChildView (cette vue enfant que j'ai simplifiée jusqu'au contrôle unique qui échoue pour cette question). Le DataContext de la vue Parent est défini comme une machine virtuelle parente dans la machine virtuelle et un DataTemplate est utilisé pour définir le contexte de ChildView. Ce DataTemplate est défini dans la vue parent.

Le problème: J'ai besoin d'afficher le nom de fichier, pas la valeur de la propriété FullFileName des objets FileInfo dans ma ListBox. J'ai défini DisplayMemberName, qui fonctionne en partie lorsque je définis comme liaison dans ChildView/UserControl. Cela ne fonctionne que sur le démarrage de l'application. Si j'ajoute un objet FileInfo à mon ChildVM - il apparaît dans le ListBox, mais n'apparaît pas comme nom de fichier. Au lieu de cela, je viens d'obtenir le FullFileName.

Il semblerait qu'il me manque un événement déclenchant la liaison, mais je ne suis pas entièrement sûr que je devrais être lié de cette façon en premier lieu.

Ceci est le code fonctionnel. S'il vous plaît noter que je l'ai simplifié pour le but de cette question. Vous pouvez ignorer les conventions de dénomination, etc.

Voici la commande usercontrol. Il s'agit d'une zone de liste contenant des objets FileInfo pour lesquels je veux définir DisplayMemberName comme valeur 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> 

Ceci est mon MainWindo Voir qui prend dans le 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> 

Ceci est la machine virtuelle pour le UserControl (UserControl est en fait partie d'une vue enfant plus compliqué que je l'ai simplifié pour cette quesiton) Dans la machine virtuelle, la zone de liste est mis à jour lorsque OnPublishDirFiles() est appelée:

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"); 
     } 
    } 
} 

Répondre

2

ne serait-il DisplayMemberPath="Name"? Je ne vois pas une propriété "FileName" réelle. Il y a Name et FullName.

+1

Comment pourrais-je être si stupide ... :( –

+0

Je connais le sentiment, regarder assez longtemps le code et commencer à voir les choses. – Laith