C# 数据绑定不更新 WPF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/357033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:22:10  来源:igfitidea点击:

C# data binding doesn't update WPF

c#.netdata-bindingxamlcode-behind

提问by Jippers

I'm trying to do a Data Binding in the C# code behind rather than the XAML. The XAML binding created in Expression Blend 2 to my CLR object works fine. My C# implementation only updates when the application is started after which subsequent changes to the CLR doesn't update my label content.

我试图在背后的 C# 代码而不是 XAML 中进行数据绑定。在 Expression Blend 2 中创建到我的 CLR 对象的 XAML 绑定工作正常。我的 C# 实现仅在应用程序启动时更新,之后对 CLR 的后续更改不会更新我的标签内容。

Here's the working XAML binding. First a ObjectDataProvider is made in my Window.Resources.

这是有效的 XAML 绑定。首先在我的 Window.Resources 中创建了一个 ObjectDataProvider。

<ObjectDataProvider x:Key="PhoneServiceDS" 
    ObjectType="{x:Type kudu:PhoneService}" d:IsDataSource="True"/>

And the label content binding:

和标签内容绑定:

<Label x:Name="DisplayName" Content="{Binding 
    Path=MyAccountService.Accounts[0].DisplayName, Mode=OneWay, 
    Source={StaticResource PhoneServiceDS}}"/>

Works great. But we want this set up in C# so we can independently change the XAML (ie. new skins). My one time working C# as follows:

效果很好。但是我们希望在 C# 中进行设置,以便我们可以独立更改 XAML(即新皮肤)。我曾经工作过的 C# 如下:

     Binding displayNameBinding = new Binding();
     displayNameBinding.Source = 
         PhoneService.MyAccountService.Accounts[0].DisplayName;
     displayNameBinding.Mode = BindingMode.OneWay;
     this.DisplayName.SetBinding(Label.ContentProperty, displayNameBinding);

This is inside my MainWindow after InitializeComponent();

这是在 InitializeComponent() 之后的我的 MainWindow 中;

Any insight why this only works on startup?

任何见解为什么这只适用于启动?

采纳答案by devios1

Your C# version does not match the XAML version. It should be possible to write a code version of your markup, though I am not familiar with ObjectDataProvider.

您的 C# 版本与 XAML 版本不匹配。应该可以编写标记的代码版本,尽管我不熟悉 ObjectDataProvider。

Try something like this:

尝试这样的事情:

Binding displayNameBinding = new Binding( "MyAccountService.Accounts[0].DisplayName" );
displayNameBinding.Source = new ObjectDataProvider { ObjectType = typeof(PhoneService), IsDataSource = true };
displayNameBinding.Mode = BindingMode.OneWay;
this.DisplayName.SetBinding(Label.ContentProperty, displayNameBinding);

回答by Jobi Joy

Write this inside Loaded event instead of Constructor. Hope you implmented INotifyPropertyChanged triggered on the DisplayName property setter?

将此写入 Loaded 事件而不是构造函数。希望您在 DisplayName 属性设置器上实现了 INotifyPropertyChanged 触发?

回答by Daniel Paull

In the priginal code you have confused the source and path.

在原始代码中,您混淆了源代码和路径。

     Binding displayNameBinding = new Binding();
     displayNameBinding.Source = PhoneService;
     displayNameBinding.Path = "MyAccountService.Accounts[0].DisplayName";
     displayNameBinding.Mode = BindingMode.OneWay;
     this.DisplayName.SetBinding(Label.ContentProperty, displayNameBinding);

(I assume PhoneService is an object instance, otherwise perhaps PhoneService. MyAccountService.Accounts[0] should be the Source?)

(我假设 PhoneService 是一个对象实例,否则可能 PhoneService.MyAccountService.Accounts[0] 应该是源?)

From memory, you can pass the path as an argument to the constructor.

从内存中,您可以将路径作为参数传递给构造函数。