I'm running onto a problem that I'm having some trouble diagnosing.
I have created a custom DataGrid object (as detailed in Sandesh's answer here) in order to be able to bind to the various selected items of the data grid. However, even though it looks like the DependecyProperty itself is getting the right value when the selection changes, the view model never seems to receive the updated value (it gets null instead).
Custom DataGrid class:
class CustomDataGrid : DataGrid
{
public CustomDataGrid()
{
this.SelectionChanged += CustomDataGrid_SelectionChanged;
}
void CustomDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList = this.SelectedItems;
}
#region SelectedItemsList
// In the setter, the value is a valid List with the correct elements.
// For some reason it doesn't seem to be passed on to the view model.
public IList SelectedItemsList
{
get { return (IList)GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList", typeof(IList), typeof(CustomDataGrid), new PropertyMetadata(OnSelectedItemsListChanged));
private static void OnSelectedItemsListChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Test");
}
#endregion
}
XAML file:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:TestViewModel />
</Window.DataContext>
<Grid>
<local:CustomDataGrid AutoGenerateColumns="True"
SelectionMode="Extended"
SelectionUnit="FullRow"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserResizeRows="False"
ItemsSource="{Binding TestModels}"
SelectedItemsList="{Binding Path=SelectedTestModels, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Window>
View Model:
class TestViewModel : INotifyPropertyChanged
{
public TestViewModel()
{
TestModels = new List<TestModel>
{
new TestModel { Name = "Test 1", ID = 1 },
new TestModel { Name = "Test 2", ID = 2 },
new TestModel { Name = "Test 3", ID = 3 },
};
}
private IEnumerable<TestModel> _testModels;
public IEnumerable<TestModel> TestModels
{
get { return _testModels; }
set
{
_testModels = value;
OnPropertyChanged();
}
}
private IEnumerable<TestModel> _selectedTestModels;
public IEnumerable<TestModel> SelectedTestModels
{
get { return _selectedTestModels; }
set
{
// Right here I would expect value to have a non-null value... but it's always null
_selectedTestModels = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var propChanged = PropertyChanged;
if (propChanged != null)
propChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
The TestModel class (very simple POCO):
class TestModel
{
public string Name { get; set; }
public int ID { get; set; }
}