In a datagrid context where there is a two way binding on the selected item, how do you prevent the g.cs code from updating the binding if multiple rows are selected?
<dataGridControl:DataGrid
SelectedItem="{x:Bind Model.SelectedItem, Mode=TwoWay}"
In a scenario where the user selects multiple rows, it uses the last selected row when when you select multiple, and of course, considering it is a two way binding, you can not clear the selected item property in the view model without clearing the entire DataGrid selection. The selected item in the view model is misleading considering multiple rows are selected, and not the last one.
The SelectedItem
is set internally and is hard to change its behavior.
Instead, you can create a custom DataGrid
control and override the SelectedItems
property with an ObservableCollection
.
public class DataGridEx : DataGrid
{
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register(
nameof(SelectedItems),
typeof(IList),
typeof(DataGridEx),
new PropertyMetadata(new ObservableCollection<object>()));
public DataGridEx() : base()
{
this.SelectionChanged += (s, e) =>
{
foreach (object item in e.RemovedItems)
{
SelectedItems.Remove(item);
}
foreach (object item in e.AddedItems)
{
SelectedItems.Add(item);
}
}
}
public new IList SelectedItems
{
get => (IList)GetValue(SelectedItemsProperty);
set => SetValue(SelectedItemsProperty, value);
}
}
UPDATE
From the comments:
What if I only want to update the selected item in the model if one row is selected, instead of using a collection?
It's hard to change the SelectedItem
behavior. I guess you can try creating a value converter. For example:
public class GreaterThanOneToNullConverter : IValueConverter
{
public object? Convert(object value, Type targetType, object parameter, string language)
{
return value is IList list && list.Count > 0
? list[0]
: null;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}