(WPF/C#)绑定到方法内的对象
为了更好地理解DataContext和绑定,我尝试制作一个示例,其中TextBlock显示对象的属性,属性值由Dispatcher决定。但是,TextBlock不会显示任何值 MainWindow.xaml:(WPF/C#)绑定到方法内的对象,c#,wpf,xaml,C#,Wpf,Xaml,为了更好地理解DataContext和绑定,我尝试制作一个示例,其中TextBlock显示对象的属性,属性值由Dispatcher决定。但是,TextBlock不会显示任何值 MainWindow.xaml: <Window x:Class="SfGauge.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microso
<Window x:Class="SfGauge.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid DataContext="{Binding myObj, Mode=TwoWay}">
<TextBlock Text="{Binding RandomVal}">
</TextBlock>
</Grid>
ObservieObject.cs
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propName));
}
}
protected bool SetProperty<T>(ref T storage, T value,
[CallerMemberName] String propertyName = null)
{
if (Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
}
公共类ObserveObject:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的void OnPropertyChanged([CallerMemberName]string propName=null)
{
var handler=PropertyChanged;
if(处理程序!=null)
{
处理程序(此,新PropertyChangedEventArgs(propName));
}
}
受保护的布尔集合属性(参考T存储,T值,
[CallerMemberName]字符串propertyName=null)
{
if(等于(存储,值))返回false;
储存=价值;
OnPropertyChanged(propertyName);
返回true;
}
}
以编程方式将DataContext
设置为myObj
:
public MainWindow()
{
InitializeComponent();
DataContext = myObj; //<--
DispatcherTimer aTimer;
aTimer = new DispatcherTimer();
aTimer.Interval += TimeSpan.FromSeconds(1);
aTimer.Tick += Timer_Tick;
aTimer.Start();
}
您只能绑定到公共属性。如果将myObj
定义为窗口类的公共属性,也可以在XAML标记中这样绑定到它:
<Grid DataContext="{Binding myObj, RelativeSource={RelativeSource AncestorType=Window}}">
元素的
DataContext
基本上只是一个对象。DataContext
的默认值是元素父元素的DataContext
,例如:
myTextBlock.DataContext = myTextBloc.Parent.DataContext
这是不“正确的”,但它说明了DataContext
是如何向下渗透的。这一直到顶部元素(在本例中为Window
)。窗口的DataContext
默认为null
当您试图绑定Grid
的DataContext
时,Binding
使用Grid
的DataContext
查找属性myObj
。Grid
的DataContext
是窗口。DataContext
是null
,这将使绑定无法工作
为了能够绑定到窗口
本身的属性,您必须将窗口
设置为自身的数据上下文
:
public MainWindow()
{
this.DataContext = this;
...
}
另外:您只能绑定到属性,因此必须将myObj
设置为属性:
public randomValue myObj { get; set; } = new randomValue()
这样做会使绑定按预期工作
或者,您也可以按照@mm8的建议直接设置文本块的数据上下文。谢谢您直观的回答!如果可以的话,我会+1:)顺便说一句,我可以看到只有当属性randomValue为public时,这才有效。但是计时器方法仍然可以访问它,所以它影响的似乎只有绑定。绑定只能访问公共属性吗?通常是。然而,这是一个特例:因为XAML和代码隐藏在技术上是同一个类,绑定
可以访问私有属性。“绑定可以访问私有属性”是错误的。WPF数据绑定仅适用于公共属性,无论它们在何处声明。
public MainWindow()
{
this.DataContext = this;
...
}
public randomValue myObj { get; set; } = new randomValue()