I have a DataGrid
bound to a collection of items (Rules). If I edit one of these items manually in the DataGrid, it seems like the SelectedItem
binding on the grid stops working (RuleListViewModelPropertyChanged
in the controller is never called again). But only if I actually change the value of the item in the cell, otherwise SelectedItem
keeps working like it should.
I have stripped the code of some irrelevant things, so this is basically what I have. First, I have the following DataGrid
:
<DataGrid x:Name="RuleTable" Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Rules}" SelectedItem="{Binding SelectedRule, Mode=TwoWay}"
BorderThickness="0" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding TargetValue, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
Header="{x:Static p:Resources.TargetValue}" Width="*" ElementStyle="{StaticResource TextCellElementStyle}"
EditingElementStyle="{StaticResource TextCellEditingStyle}"/>
</DataGrid.Columns>
</DataGrid>
With a ViewModel
that looks like this:
public class RuleListViewModel : ViewModel<IRuleListView>
{
private IEnumerable<Rule> rules;
private Rule selectedRule;
public RuleListViewModel(IRuleListView view)
: base(view)
{
}
public RuleListViewModel() : base(null) {}
public IEnumerable<Rule> Rules
{
get
{
return rules;
}
set
{
if (rules != value)
{
rules = value;
RaisePropertyChanged("Rules");
}
}
}
public Rule SelectedRule
{
get
{
return selectedRule;
}
set
{
if (selectedRule != value)
{
selectedRule = value;
RaisePropertyChanged("SelectedRule");
}
}
}
}
And finally a Controller
that looks like this:
public class RuleController : Controller
{
private readonly IShellService shellService;
private readonly RuleListViewModel ruleListViewModel;
private readonly DelegateCommand addRuleCommand;
private readonly DelegateCommand deleteRuleCommand;
[ImportingConstructor]
public RuleController(IShellService shellService, IEntityService entityService, RuleListViewModel ruleListViewModel)
{
this.shellService = shellService;
this.ruleListViewModel = ruleListViewModel;
}
public void Initialize()
{
AddWeakEventListener(ruleListViewModel, RuleListViewModelPropertyChanged);
shellService.RuleListView = ruleListViewModel.View;
List<Rule> rules = GetRules();
ruleListViewModel.Rules = new ObservableCollection<Rule>(rules);
}
private void RuleListViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "SelectedRule")
{
// This never gets called after edit
}
}
}
I have really no idea what the problem is, but since I actually have to change the value to experience this behavior (only clicking in the cell and not editing anything works fine) I'm guessing it has something to do with the SelectedItem
binding breaking when I change the value of the item bound to it?!
For anyone who comes across this thread and you are using ObservableCollection - check to see if you override GetHashCode() (I was doing equality testing via IEquatable). The bindings to SelectedItem and SelectedIndex break as soon as you make a change to a cell.
From MSDN (https://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx):
"You can ensure that the hash code of a mutable object does not change while the object is contained in a collection that relies on its hash code."
And of course I was getting a hash on the editable (i.e. mutable) field...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With