Wpf数据表格在单元格编辑后失去绑定的选定项

5
我有一个绑定到项目集合(规则)的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绑定有关,当我更改绑定到它的项目的值时绑定可能会失效?!

3个回答

7
如果有人遇到这个问题并且正在使用ObservableCollection,请检查是否覆盖了GetHashCode()方法(我通过IEquatable进行相等性测试)。当您对单元格进行更改时,SelectedItem和SelectedIndex的绑定会中断。

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

“您可以确保可变对象的哈希代码在包含它的依赖其哈希代码的集合中不会更改。”

当然,我正在获取可编辑字段的哈希值...

0

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

阅读这篇文章可能会有所帮助:WPF DataGrid source updating on cell changed


谢谢您的回复,但那不是问题所在。原因是我的 DataModel 没有继承自 System.Waf.Applications.DataModel(也许我应该提到我正在使用 WPF 应用程序框架)。 - Joel

0
原来问题出在我忘记让我的数据模型继承自System.Waf.Applications.DataModel(也许我应该提一下我正在使用WPF应用程序框架)。
我猜这可能与未处理PropertyChanged事件有关。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接