为什么当 this.DataContext = this 时绑定到我的 class 的实例不起作用
Why does Binding to an instance of my class not work when this.DataContext = this
我有一个 class,它定义了一个预配置的套接字以及远程访问和控制特定设备所需的所有方法。 class 的一部分包括一个对象的实例,该对象保存设备各个方面的当前状态。对象中的每一项都使用 INotifyPropertyUpdate 报告更新。当我将它插入我的测试程序时,所有方法都被调用并正确执行,但我似乎能够更新状态以显示在 UI 中的唯一方法是将 DataContext 设置为class 实例中的 "Current" 对象。如果我将 DataContext 设置为 class 的实例或 UI,我将停止在 UI 中获取更新。我希望能够使用 UI 作为 DataContext,然后使用 {Binding Path=InstanceOfMyClass.Current.StatusItemA}
绑定到 XAML
有问题的 classes 的相关部分:
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 项目。我之前的所有项目都是 vb.net 在 WinForms 中进行的,所以我在学习曲线上略有障碍。我想学习实现此项目目标的正确方法,此时只需完成 UI。
CurrentStatusObject 在内部通知更改并且确实有效。问题是,如果我将 UI 的 DataContext 设置为那个对象,则更改只会反映在用户界面中。我希望能够将 DataContext 设置为包含更广泛的范围。如果我可以使用 MyClass 的实例作为 DataContext,我会很高兴,但现在无法正常工作。
问题是为什么?以及如何让它工作(使用正确的做法)?
我猜你打错了...
public _Current Current = new _Current();
但如果是这样的话,这是一个字段而不是 属性。如果您将其更改为此,那么绑定可能会起作用
private _Current _current = new _Current();
public _Current Current
{
get
{
return _current;
}
}
B.T.W:在您的 class 姓名中使用下划线是不标准的。删除它应该是你所需要的
您只能绑定到 属性,不能绑定字段。
InstanceOfMyClass
和 Current
需要先声明为属性,然后才能绑定到它(以使 DataContext = this
起作用)。
顺便说一句,MVVM 规定您不应将视图代码隐藏用作视图模型。你应该有一个单独的class。
我有一个 class,它定义了一个预配置的套接字以及远程访问和控制特定设备所需的所有方法。 class 的一部分包括一个对象的实例,该对象保存设备各个方面的当前状态。对象中的每一项都使用 INotifyPropertyUpdate 报告更新。当我将它插入我的测试程序时,所有方法都被调用并正确执行,但我似乎能够更新状态以显示在 UI 中的唯一方法是将 DataContext 设置为class 实例中的 "Current" 对象。如果我将 DataContext 设置为 class 的实例或 UI,我将停止在 UI 中获取更新。我希望能够使用 UI 作为 DataContext,然后使用 {Binding Path=InstanceOfMyClass.Current.StatusItemA}
有问题的 classes 的相关部分:
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 项目。我之前的所有项目都是 vb.net 在 WinForms 中进行的,所以我在学习曲线上略有障碍。我想学习实现此项目目标的正确方法,此时只需完成 UI。
CurrentStatusObject 在内部通知更改并且确实有效。问题是,如果我将 UI 的 DataContext 设置为那个对象,则更改只会反映在用户界面中。我希望能够将 DataContext 设置为包含更广泛的范围。如果我可以使用 MyClass 的实例作为 DataContext,我会很高兴,但现在无法正常工作。
问题是为什么?以及如何让它工作(使用正确的做法)?
我猜你打错了...
public _Current Current = new _Current();
但如果是这样的话,这是一个字段而不是 属性。如果您将其更改为此,那么绑定可能会起作用
private _Current _current = new _Current();
public _Current Current
{
get
{
return _current;
}
}
B.T.W:在您的 class 姓名中使用下划线是不标准的。删除它应该是你所需要的
您只能绑定到 属性,不能绑定字段。
InstanceOfMyClass
和 Current
需要先声明为属性,然后才能绑定到它(以使 DataContext = this
起作用)。
顺便说一句,MVVM 规定您不应将视图代码隐藏用作视图模型。你应该有一个单独的class。