简体   繁体   English

当this.DataContext = this时,为什么绑定到我的类的实例不起作用

[英]Why does Binding to an instance of my class not work when this.DataContext = this

I have a class that defines a preconfigured socket and all the methods needed to access and control a specific piece of equipment remotely. 我有一个类,它定义了一个预先配置的套接字以及远程访问和控制特定设备所需的所有方法。 Part of the class includes an instance of an object that holds the current status of various aspects of the equipment. 该类的一部分包括一个对象的实例,该对象保存设备各个方面的当前状态。 Each item in the object reports updates using INotifyPropertyUpdate. 对象中的每个项目都使用INotifyPropertyUpdate报告更新。 When I plug it into my test program, all of the methods are called and execute properly, but the only way I seem to be able to get updates of the status to show in the UI is when the DataContext is set to the "Current" object inside the instance of the class. 当我将它插入我的测试程序时,所有方法都被调用并正确执行,但我似乎能够获得要在UI中显示的状态更新的唯一方法是将DataContext设置为“当前”类实例中的对象。 If I set the DataContext to the instance of the class, or to the UI, I stop getting updates in the UI. 如果我将DataContext设置为类的实例或UI,我将停止在UI中获取更新。 I would like to be able to use the UI as the DataContext and then bind in the XAML using {Binding Path=InstanceOfMyClass.Current.StatusItemA} 我希望能够使用UI作为DataContext,然后使用{Binding Path=InstanceOfMyClass.Current.StatusItemA}在XAML中{Binding Path=InstanceOfMyClass.Current.StatusItemA}

The pertinent parts of the classes in question: 相关课程的相关部分:

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

This works: 这有效:

c# C#

this.DataContext = this.InstanceOfMyClass.Current;

XAML XAML

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

This does not work, but I want it to: 这不起作用,但我希望它:

c# C#

this.DataContext = this;

XAML XAML

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

Nor does this: 这也不是:

c# C#

this.DataContext = this.InstanceOfMyClass;

XAML XAML

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

I didn't see any answers when searching, but sometimes my research skills fail me. 我在搜索时没有看到任何答案,但有时我的研究技巧让我失望。 Any help would be appreciated. 任何帮助,将不胜感激。 I enjoy learning new ways of coding. 我喜欢学习新的编码方式。 This is my first c# or wpf project. 这是我的第一个c#或wpf项目。 All my projects previous to this have been vb.net in WinForms so I'm at a slight handicap with the learning curve. 我之前的所有项目都是WinForms中的vb.net,所以我对学习曲线略有不利。 I would like to learn the correct way to reach my goals for this project, which at this point is simply completing the UI. 我想了解实现此项目目标的正确方法,此时只需完成UI。

The CurrentStatusObject notifies changes internally and that does work. CurrentStatusObject在内部通知更改,并且确实有效。 The problem is that the changes are only reflected in the User Interface if I set the DataContext for the UI to that one object. 问题是,如果我将UI的DataContext设置为该对象,则更改仅反映在用户界面中。 I want to be able to set the DataContext to include a wider scope. 我希望能够将DataContext设置为包含更广泛的范围。 I would be happy if I could use the instance of MyClass as the DataContext, but that is not working right now. 如果我可以使用MyClass的实例作为DataContext,我会很高兴,但现在不能正常工作。

The question is Why? 问题是为什么? and How do I get it to work (using correct practices)? 我如何让它工作(使用正确的做法)?

I presume you have a typo... 我猜你有一个错字......

public _Current Current = new _Current();

But if so this is a field and not a property. 但如果是这样,这是一个领域而不是财产。 If you change it to this then the binding might work 如果将其更改为此,则绑定可能会起作用

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

BTW: it is not standard to use underscore as part of your class name. 顺便说一句:使用下划线作为班级名称的一部分是不标准的。 Removing it should be all you need 删除它应该是你所需要的

You can only bind to Properties , never fields. 您只能绑定到属性 ,而不能绑定到字段。

InstanceOfMyClass and Current needs to be declared as properties before you can bind to it (to make DataContext = this work). InstanceOfMyClassCurrent需要在绑定到它之前声明为属性(使DataContext = this工作)。

As an aside, MVVM dictates that you shouldn't be using your View code-behind as the view model. 另外,MVVM规定您不应将View代码隐藏用作视图模型。 You should have a separate class for that. 你应该有一个单独的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM