【问题标题】:WPF DataBinding with Code First Entity FrameworkWPF DataBinding 与 Code First 实体框架
【发布时间】:2012-06-24 21:21:53
【问题描述】:

我刚刚熟悉 WPF 数据绑定。我已经了解了大部分基础知识,但我无法弄清楚一些事情。

首先,假设我有一个名为 Synth 的对象,它有一个 Bank 集合。反过来,银行有一组补丁。我有一个合成器窗口,我将 DataContext 设置为单个合成器对象。我有一个列表框 (lstBanks) 显示所有银行 ({Binding Banks}) 和另一个 (lstPatches) 显示所有补丁 ({Binding ElementName=lstBanks, Path=SelectedItem.Patches})。这一切都很好。当我选择银行时,我会看到适用的补丁。

问题 1:如何将选定的 Patch 加载到具有双向绑定的对话框窗口中,但如果 DialogResult = false 则取消这些更改?

现在,我有一个补丁对话框,它在构造函数中接收一个补丁,它设置为它的 DataContext,但我只使用 OneWay 绑定。这发生在双击 lstPatches 时。

    private void Patch_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        Models.Patch patch = (Models.Patch)((ListBoxItem)sender).DataContext;

        PatchEdit p = new PatchEdit(patch);
        p.Owner = this;
        if (p.ShowDialog().GetValueOrDefault())
        {
            // Do stuff if applicable
        }
    }

这是我的 PatchEdit 构造函数和 OK 按钮事件:

    public PatchEdit(Models.Patch Patch) : this()
    {
        this.DataContext = Patch;
    }

    private void btnOK_Click(object sender, RoutedEventArgs e)
    {
        Models.Patch p = (Models.Patch)DataContext;
        p.Name = txtName.Text;
        p.MidiProgramChangeValue = int.Parse(txtPCN.Text);
        this.DialogResult = true;
        this.Close();
    }

如果用户在补丁对话框上单击“确定”,那是我将表单中的属性设置回 DataContext 的时候。我不确定这是否是最好的方法。在用户单击主合成器窗口上的确定之前,我不想真正保存更改。因此,所有音色库和补丁编辑都应该只保留在本地,并且只有在用户单击“确定”而不是对话框上的“取消”时才“本地”提交。

问题 2:通过对话框更新补丁后,我如何才能在 lstPatches 中反映该更改?

我知道直接导航我的模型是 DBSet 类型必不可少的,这不是 Observable。我看过有关使用 Observable 集合的帖子,但这不只是使 WPF 数据绑定应该很容易的事情变得复杂吗?如果这是唯一的方法,我如何使用我的代码优先模型轻松完成此任务?

【问题讨论】:

    标签: wpf data-binding ef-code-first


    【解决方案1】:

    问题 1: 绑定到第二个/临时对象。如果用户取消,请将其丢弃。如果他们不这样做,请使用它来更新您的原始对象。数据绑定并没有真正提供“撤消”或“重置”方法。

    问题 2: 不,使用 ObservableCollection 不会使事情复杂化。这是推荐的做事方式。实际上,没有他们更难工作。

    【讨论】:

    • 谢谢,关于问题 1,这正是我现在使用 OneWay 绑定所做的,这很好。对于问题 2,您可以举个例子吗?如何使用 IObservable 包装我的 DBSet 而不会变得太复杂?
    • 这不是你想做的。 ObservableCollection<EntityObject> 将管理集合的更新(添加/删除),但不管理每个单独对象的属性。要处理单个项目的更新,您需要为实现INotifyProperyChanged 的对象创建一个 ViewModel。如果你这样做,你就可以创建一个ObservableCollection<ViewModel>。
    • 嗯。我不确定这是否正确,但我在我的代码第一类中实现了 INotifyPropertyChanged。然后,我在我的代码第一类中将我的所有集合声明为 IObservable (public virtual ObservableCollection Patches { get; set; })。当然,我在所有属性上调用我的 OnPropertyChanged。这实际上现在在我的银行列表框上运行良好。但是,即使 Bank.Patches 是一个 Observable 集合,我的补丁列表框仍然没有更新。意见或想法?
    • 啊,没关系。我在 Patch 中重写了 ToString() 并且从未设置过 DisplayMemberPath。这解释了为什么它从未更新。一旦我开始使用带有具体绑定的 ItemTemplate,它就开始按预期工作。
    • 你真的不应该在代码第一类中这样做。看看这篇文章:msdn.microsoft.com/en-us/magazine/dd419663.aspx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多