为了更好地理解DataContext和绑定,我试图做一个示例,其中TextBlock显示对象的属性,其中属性值由DispatcherTimer决定。但是,TextBlock不会显示任何值。
MainWindow.xaml:
<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>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
randomValue myObj = new randomValue();
public MainWindow()
{
InitializeComponent();
DispatcherTimer aTimer;
aTimer = new DispatcherTimer();
aTimer.Interval += TimeSpan.FromSeconds(1);
aTimer.Tick += Timer_Tick;
aTimer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
Dispatcher.Invoke(() =>
{
myObj.giveRandom();
});
}
}
public class randomValue : ObservableObject
{
Random r = new Random();
private int randomval;
public int RandomVal { get
{
return randomval;
}
set
{
SetProperty(ref randomval, value);
}
}
public void giveRandom()
{
RandomVal = r.Next(0, 100);
}
public randomValue()
{
RandomVal = 0;
}
}
ObservableObject.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;
}
}
答案 0 :(得分:0)
以编程方式将DataContext
设置为myObj
:
public MainWindow()
{
InitializeComponent();
DataContext = myObj; //<--
DispatcherTimer aTimer;
aTimer = new DispatcherTimer();
aTimer.Interval += TimeSpan.FromSeconds(1);
aTimer.Tick += Timer_Tick;
aTimer.Start();
}
这不起作用:
DataContext="{Binding myObj, Mode=TwoWay}"
您只能绑定到公共属性。如果将myObj
定义为窗口类的公共属性,也可以在XAML标记中将其绑定到它:
<Grid DataContext="{Binding myObj, RelativeSource={RelativeSource AncestorType=Window}}">
答案 1 :(得分:0)
元素的DataContext
基本上只是一个对象。默认值DataContext
是元素父级的DataContext
,例如:
myTextBlock.DataContext = myTextBloc.Parent.DataContext
这不是正确的&#34;,但它说明了DataContext
如何逐渐减少。这一直到顶部元素(在这种情况下为Window
)。 Window
&#39; DataContext
默认为null
。
当您尝试绑定DataContext
Grid
时,Binding
使用DataContext
的{{1}}来查找属性{{ 1}}。 Grid
的{{1}}为myObj
DataContext
,这会使Grid
无效。
为了能够绑定Window.DataContext
本身的属性,您必须将null
设置为自己的Binding
:
Window
此外:您只能绑定到属性,因此您必须将Window
作为属性:
DataContext
这样做可以让你的绑定按预期工作。
或者您可以按@ mm8建议并直接设置public MainWindow()
{
this.DataContext = this;
...
}
的{{1}}。