【发布时间】:2015-10-11 22:16:08
【问题描述】:
我目前正在尝试使用新编译的绑定,并且(再次)达到了我在谜题中遗漏的一点:为什么我必须调用Bindings.Update?到目前为止,我认为实现INotifyPropertyChanged 就足够了吗?
在我的示例中,如果我调用这个神秘的方法(由编译的绑定自动生成),GUI 只会显示正确的值。
我正在使用具有以下(此处为简化)xaml 语法的用户控件:
<UserControl>
<TextBlock Text="x:Bind TextValue"/>
</UserControl>
其中TextValue 是此用户控件的简单依赖属性。在一个页面中,我将此控件用作:
<Page>
<SampleControl TextValue="{x:Bind ViewModel.Instance.Name}"/>
</Page>
地点:
-
ViewModel是在运行InitializeComponent()之前设置的标准属性 -
Instance是一个实现INotifyPropertyChanged的简单对象
加载Instance 后,我为Instance 引发属性更改事件。我什至可以调试到用户控件的依赖属性TextValue 获得正确 值的行——但没有显示任何内容。只有当我调用Bindings.Update() 时,才会显示该值。我在这里错过了什么?
更新
我也不使用{x:Bind ... Mode=OneWay}。
更多代码
Person.cs:
using System.ComponentModel;
using System.Threading.Tasks;
namespace App1 {
public class Person : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name { get {
return this.name;
}
set {
name = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public class ViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private Person instance;
public Person Instance {
get {
return instance;
}
set {
instance = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Instance"));
}
}
public Task Load() {
return Task.Delay(1000).ContinueWith((t) => {
var person = new Person() { Name = "Sample Person" };
this.Instance = person;
});
}
}
}
SampleControl.cs:
<UserControl
x:Class="App1.SampleControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100"
d:DesignWidth="100">
<TextBlock Text="{x:Bind TextValue, Mode=OneWay}"/>
</UserControl>
SampleControl.xaml.cs:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App1 {
public sealed partial class SampleControl : UserControl {
public SampleControl() {
this.InitializeComponent();
}
public string TextValue {
get { return (string)GetValue(TextValueProperty); }
set { SetValue(TextValueProperty, value); }
}
public static readonly DependencyProperty TextValueProperty =
DependencyProperty.Register("TextValue", typeof(string), typeof(SampleControl), new PropertyMetadata(string.Empty));
}
}
MainPage.xaml:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:SampleControl TextValue="{x:Bind ViewModel.Instance.Name, Mode=OneWay}"/>
</StackPanel>
</Page>
MainPage.xaml.cs:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App1 {
public sealed partial class MainPage : Page
{
public MainPage()
{
this.DataContext = new ViewModel();
this.Loaded += MainPage_Loaded;
this.InitializeComponent();
}
public ViewModel ViewModel {
get {
return DataContext as ViewModel;
}
}
private void MainPage_Loaded(object sender, RoutedEventArgs e) {
ViewModel.Load();
Bindings.Update(); /* <<<<< Why ????? */
}
}
}
另一个更新
我更新了Load 方法以使用任务(参见上面的代码)!
【问题讨论】:
-
请贴出您的视图背后的代码和视图模型代码,也许我们可以提供帮助
-
我添加了所有相关代码。仅当我包含
Bindings.Update();时,主页才会显示“样本人”。 -
感谢您提出的好问题!顺便说一句,Mode=OneWay 适用于我的 UWP 应用程序。您的问题和出色的回答说服了我继续使用 Binding。它可以使用很多改进,但不是 x:Bind 提供的。如果 MSFT 想改进 Binding,就看看数据绑定新人使用的强大的表达式语言——Android。
标签: c# windows-runtime winrt-xaml win-universal-app