【问题标题】:Why does Binding to an instance of my class not work when this.DataContext = this为什么当 this.DataContext = this 时绑定到我的类的实例不起作用
【发布时间】:2015-03-21 22:40:11
【问题描述】:

我有一个类,它定义了一个预配置的套接字以及远程访问和控制特定设备所需的所有方法。该类的一部分包括一个对象的实例,该实例保存设备各个方面的当前状态。对象中的每个项目都使用 INotifyPropertyUpdate 报告更新。当我将它插入我的测试程序时,所有的方法都被调用并正确执行,但我似乎能够获得状态更新以显示在 UI 中的唯一方法是将 DataContext 设置为“当前”类实例中的对象。如果我将 DataContext 设置为类的实例或 UI,我将停止在 UI 中获取更新。我希望能够将 UI 用作 DataContext,然后使用 {Binding Path=InstanceOfMyClass.Current.StatusItemA} 绑定到 XAML 中

相关类的相关部分:

public MyClass : Socket, INotifyPropertyChanged // INotifyPropertyChanged is also used to notify changes in other parts of the class
{
    public MyClass : base(//socket configuration info here)
    {}

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private CurrentStatusObject _current = new CurrentStatusObject();
    public CurrentStatusObject Current
    {
        get { return _current; }
        set
        {
            if (_current != value)
            {
                _current = value;
                NotifyPropertyChanged();
            }
        }
    }

    // other methods and properties etc.
}

// this is the Current status object
public class CurrentStatusObject : object, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private string _statusItemA;

    public string StatusItemA
    {
        get { return _statusItemA; }
        set
        {
            if (_statusItemA != value)
            {
                _statusItemA = value;
                NotifyPropertyChanged(); // not necessary to pass property name because of [CallerMemberName]
            }
        }
    }

这行得通:

c#

this.DataContext = this.InstanceOfMyClass.Current;

XAML

<Label Content="{Binding Path=StatusItemA, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>

这不起作用,但我希望它:

c#

this.DataContext = this;

XAML

<Label Content="{Binding Path=InstanceOfMyClass.Current.StatusItemA, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>

这也不是:

c#

this.DataContext = this.InstanceOfMyClass;

XAML

<Label Content="{Binding Path=Current.StatusItemA, Mode=OneWay, UpdateSourceTrigger}"/>

我在搜索时没有看到任何答案,但有时我的研究技能让我失望。任何帮助,将不胜感激。我喜欢学习新的编码方式。这是我的第一个 c# 或 wpf 项目。在此之前我的所有项目都是 WinForms 中的 vb.net,所以我在学习曲线上略有障碍。我想学习实现这个项目目标的正确方法,此时它只是完成 UI。

CurrentStatusObject 在内部通知更改并且确实有效。问题是,如果我将 UI 的 DataContext 设置为那个对象,这些更改只会反映在用户界面中。我希望能够设置 DataContext 以包含更广泛的范围。如果我可以使用 MyClass 的实例作为 DataContext,我会很高兴,但现在不行。

问题是为什么?以及如何让它发挥作用(使用正确的做法)?

【问题讨论】:

  • 首先你的数据上下文应该是一个视图模型并且从不视图。但是,这并不能回答您的问题。对于后两个选项,您会看到哪些绑定错误?这些将在输出窗口中显示为System.Data 异常。
  • @Bradley 输出窗口没有显示任何错误。我的用户界面根本不显示当前对象中的数据,除非将我的类实例中的当前对象设置为数据上下文
  • 你能显示InstanceOfMyClass的声明吗?使用属性是否偶然修复了最终选项?
  • 您可以尝试将InstanceOfMyClass 也设为属性吗?这将解决您的第二个示例,很可能是最后一个示例。
  • @bradley [用脚开枪] 我忘记在重建前清洁了。属性解决方案确实适用于最后一个选项。正如您建议的那样,它也适用于其他选项。你真棒。谢谢!!!

标签: c# wpf xaml binding datacontext


【解决方案1】:

我想你有一个错字...

public _Current Current = new _Current();

但如果是这样,这是一个字段而不是属性。如果你把它改成这个,那么绑定可能会起作用

private _Current _current = new _Current();
public _Current Current
{
    get 
    {
        return _current;
     }
} 

顺便说一句:使用下划线作为类名的一部分是不标准的。删除它应该是你所需要的一切

【讨论】:

  • 很好,我敢打赌这就是它的原因。
  • @qwert - 错字仅在我的帖子中。至于测试您建议的答案,我在重建之前忘记清理了。将“当前”从字段更改为属性可用于设置 this.DataContext = MyClass。正如@BradleyDotNET 所建议的那样,将 InstanceOfMyClass 声明为属性也可以让我设置this.DataContext = this,这最终对我来说是最好的情况。多谢你们。你太棒了!!!
【解决方案2】:

您只能绑定到属性,不能绑定到字段。

InstanceOfMyClassCurrent 需要先声明为属性,然后才能绑定到它(使DataContext = this 工作)。

顺便说一句,MVVM 规定您不应使用 View 代码隐藏作为视图模型。你应该有一个单独的类。

【讨论】:

  • 您能否建议一些搜索词来为我指明正确的方向,以便学习正确实现视图和视图模型?
  • @LukeN MVVM 开始,如果你在谷歌上搜索“WPF 中的 MVVM”,这里有很多很棒的文章可以帮助你入门。
猜你喜欢
  • 2021-06-07
  • 2011-01-16
  • 1970-01-01
  • 2023-03-09
  • 2014-07-24
  • 2011-09-29
  • 2013-02-18
  • 2020-05-21
  • 1970-01-01
相关资源
最近更新 更多