Reputation: 2304
I have a DisplayMemberPath value that is failing.
The set up of my project is that I have a ParentView which contains a ChildView (this child view I have simplified down to the single control that is failing for this question). The DataContext of the Parent view is set a Parent VM in the VM and a DataTemplate is used to set the context of the ChildView. That DataTemplate is set in the Parent View.
The Problem: I need to display the FileName, not the FullFileName property value of the FileInfo objects in my ListBox. I've set DisplayMemberName, which works partly when I set as binding in the ChildView/UserControl. That is it only works on start up of the application. If I add a FileInfo Object to my ChildVM - it shows up in the ListBox, but doesn't show up as FileName. Instead I just get the FullFileName.
It would stand to reason that I'm missing an event triggering the binding, but I'm not entirely sure I should be binding this way in the first place.
This is the functional code. Please note i have simplified it for the purpose of this question. You can ignore naming conventions, etc.
Here is the usercontrol. It is a list box containing FileInfo objects for which I want to set the DisplayMemberName to be the FileInfo.FileName value.
<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>
This is my MainWindo View which takes in the 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>
This is the VM for the UserControl (The usercontrol is actually part of a more complicated child view I have simplified for this quesiton) In the VM, the listbox is updated when OnPublishDirFiles() is called:
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");
}
}
}
Upvotes: 1
Views: 43
Reputation: 6091
Wouldn't it be DisplayMemberPath="Name"
? I don't see an actual "FileName" property. There's Name
and FullName
.
Upvotes: 2