【问题标题】:How do I data bind to a single instance of an object in C# WPF?如何在 C# WPF 中将数据绑定到对象的单个实例?
【发布时间】:2021-12-16 02:21:40
【问题描述】:

我正在编写一个 WPF 页面来更新存储在 SQL 服务器上的数据,而我编写它的方式需要存储原始数据的副本以创建 WHERE 子句。
所以,我想做的是将两个数据副本存储在页面上的变量中。一个保留为原始对象,一个用作数据绑定上下文,声明如下:

public Object Current { get; set; }
private readonly Object Start = new Object();

在我的构造函数中声明为:

public PageUpdate(Object source) {
    InitializeComponent();
    Current = source;
    Start = source;
}

如果我对数据绑定的理解是正确的,数据绑定应该是完全看不到Start对象的。 我尝试了几种方法,包括使用DataContext = Current; 设置数据上下文,使用 XAML 以两种不同的方式对其进行描述:

<TextBox x:Name="TextBox1" Text="{Binding Object.ObjectTextProperty, RelativeSource={RelativeSource FindAncestor AncestorType=Page}" />
<Page d:DataContext="{d:DesignInstance Type=Object}">
    <TextBox x:Name="TextBox1" Text="{Binding ObjectTextProperty}" />
</Page>

最后尝试在代码隐藏中设置每个绑定属性:

TextBox1.SetBinding(TextBox.TextProperty, new Binding("ObjectTextProperty")
    {
        BindingGroupName = "bindingGroup",
        Source = Current,
        Mode = BindingMode.TwoWay
    });

以及上述的各种组合。

每次我使用它时,我都会在从前端编辑数据后通过将 Start 和 Current 打印到调试控制台进行测试,并且它始终将两个对象显示为相同,尽管据我所知, Start 应该永远不会被数据绑定改变。

我在这里遗漏了什么明显的东西还是应该采取不同的方法?

【问题讨论】:

  • 看看 IEditableObject 接口。它与 MVVM 和 WPF DataBinding 配合得很好:docs.microsoft.com/en-us/dotnet/api/… 另外:stackoverflow.com/questions/4410327/ieditableobject-in-mvvm
  • 您实际分配给 Start 和 Current 的对象是什么?我假设它是一种引用类型,在这种情况下您不会获得对象的副本,因此更改属性将反映在两个变量中。
  • @Steeeve 我刚刚编辑了问题以显示构造函数在哪里分配了这两个东西。该对象是从另一个具有 ObservableCollection 的页面复制的,唯一更改的项目是在 Update 页面上以某种方式打开的项目。
  • 那么对象的实际类型是什么?它是否支持克隆之类的东西?否则你会有两个指向同一个对象的引用。
  • @Steeeve 这可以解释很多...我将不得不查找克隆。该对象是我自己创建的自定义对象。

标签: c# wpf data-binding


【解决方案1】:

原来我需要做的是在 Object 上实现 ICloneable 接口,然后简单地克隆该对象。

我在我的 Object 类中添加了以下内容:

public class Object : ICloneable
{
    public object Clone()
    {
        return MemberWiseClone();
    }
}

然后我对页面构造函数进行了以下更改:

public PageUpdate(Object source) {
    InitializeComponent();
    Current = source;
    Start = (Object)source.Clone();
}

我希望这可以帮助其他遇到此问题的人。

感谢 Steeeve 的解决方案。

【讨论】:

  • 注意:MemberwiseClone 返回您的类的浅表副本。如果你的类只有值类型的属性,那很好。但是,如果您有任何引用类型的属性,则需要克隆它们,而不仅仅是对它们的引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多