Wpf DataGrid SelectedItem在单元格编辑后失去绑定

本文关键字:失去 绑定 编辑 单元格 DataGrid SelectedItem Wpf | 更新日期: 2023-09-27 17:51:11

我有一个DataGrid绑定到一个项目集合(规则)。如果我在DataGrid中手动编辑其中一个项目,似乎网格上的SelectedItem绑定停止工作(控制器中的RuleListViewModelPropertyChanged再也不会被调用)。但只有当我实际改变单元格中项目的值时,否则SelectedItem保持正常工作。

我已经剥离了一些不相关的东西,所以这基本上是我所拥有的。首先,我有以下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>

ViewModel看起来像这样:

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

最后一个Controller看起来像这样:

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
        }
    }
}

我真的不知道问题是什么,但是因为我实际上必须改变值来体验这种行为(只在单元格中单击而不编辑任何东西都可以正常工作),我猜它与SelectedItem绑定中断有关,当我改变绑定到它的项目的值时?!

Wpf DataGrid SelectedItem在单元格编辑后失去绑定

对于任何遇到此线程并且您正在使用ObservableCollection的人-检查是否覆盖GetHashCode()(我正在通过IEquatable进行平等测试)。一旦更改单元格,对SelectedItem和selecteindex的绑定就会中断。

From MSDN (https://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx):

"你可以确保一个可变对象的哈希码在对象被包含在一个依赖其哈希码的集合中时不会改变。"

当然,我得到一个哈希上的可编辑(即可变)字段…

我认为这是因为datagrid使用了Bindingroups,所以当你输入一个单元格时,每个UI事件都被绕过,直到你验证并离开行。

阅读这篇文章可能会有所帮助:WPF DataGrid源更新单元格更改

所以事实证明,这是因为我忘记让我的数据模型从System.Waf.Applications.DataModel继承(也许我应该提到我正在使用WPF应用程序框架)。

我猜这与PropertyChanged事件没有被处理有关。