我是WPF的新手并尝试了一个简单的数据绑定示例,但它不起作用。 我的窗口有一个TextBlock,它绑定到window对象的一个属性。 我在代码中声明了该属性。
运行时,我看到TextBlock中出现正确的值。 还有一个按钮,点击它时会更新属性,但我没有看到这会影响TextBlock。
我已经正确地实现了INotifyPropertyChanged,据我所知。我还看到,在调试时,某事订阅了PropertyChanged事件,除了它似乎没有做任何事情。
我有两个问题:
1)为什么这不按预期工作?
2)有没有简单的方法在运行时调试导致这种情况的原因,而不使用第三方工具?从我粗略的知识来看,在我看来,WPF中的调试支持非常缺乏。
XAML是(不包括“标准”XAML窗口元素):
<TextBlock Height="28" Name="label1" VerticalAlignment="Top"
Text="{Binding Path=TheName}"
Grid.Row="0"
></TextBlock>
<Button Height="23" Name="button1" VerticalAlignment="Stretch" Grid.Row="1"
Click="button1_Click">
Button
</Button>
窗口类中的代码是:
public partial class Window1 : Window
{
protected MyDataSource TheSource { get; set; }
public Window1()
{
InitializeComponent();
TheSource = new MyDataSource();
TheSource.TheName = "Original"; // This works
this.label1.DataContext = this.TheSource;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
TheSource.TheName = "Changed"; // This doesn't work
}
}
public class MyDataSource : INotifyPropertyChanged
{
string thename;
public string TheName
{
get { return thename; }
set { thename = value; OnPropertyChanged(thename); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
答案 0 :(得分:7)
问题在于你的“TheName”属性设置器。 OnPropertyChanged方法调用正在传递“thename”的值,而不是“thename”的“名称”。 (对不起,如果这没有意义 - 用于示例的变量名称与我们密谋!)
正确的代码是:
string thename;
public string TheName
{
get { return thename; }
set { thename = value; OnPropertyChanged("TheName"); }
}
希望这有帮助!
答案 1 :(得分:3)
来自Bea Stollnitz博客,以下是调试WPF绑定的几种方法。
检查输出窗口,因为WPF记录了很多错误
您可以将trace源添加到app.config中。有关Mike Hillberg’s blog
为绑定添加跟踪级别(这是我最喜欢的)。添加名称空间xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
在您的绑定中添加跟踪级别<TextBlock Text="{Binding Path=TheName, diagnostics:PresentationTraceSources.TraceLevel=High}" />
将转换器添加到绑定中,然后在转换器中放置一个断点。
答案 2 :(得分:0)
好的,谢谢,在阅读有关PropertyChangedEventArgs参数时,我没有给予足够的重视。 似乎脆弱的设计依赖于字符串作为属性名称,但显然其他人也这么认为(来自用户评论的链接底部链接到您链接到的MSDN页面)。
然而,我的第二个问题仍然没有答案:我怎么能调试这个并找出我做错了什么?
例如,WPF不以某种形式记录其操作吗?它应该注意到我没有在这个对象上有一个名为“Changed”的属性,为什么不引发异常或者至少写一些东西到调试控制台?