UWP中C#代码设置数据绑定不更新UI问题求助
嘿,我之前也踩过这个SetBinding的坑,咱们来一步步拆解问题所在~
你碰到的情况是:初始绑定显示正常,但当ViewModel里的Item属性换成新实例时,UI完全没反应,而用{x:Bind}就一切正常。核心原因是你当前的绑定源指向的是旧的Item实例,没有跟踪ViewModel的Item属性变化。
为什么原来的代码失效?
先看你这段绑定代码:
txtInformation.SetBinding(TextBlock.TextProperty, new Binding() { Mode = BindingMode.OneWay, Source = ViewModel.Item, // 这里绑定的是ViewModel.Item的当前实例 Path = new PropertyPath("Information"), TargetNullValue = "No information found" });
初始化时,Source = ViewModel.Item会把绑定的源设置为当时的MyObject实例。之后如果ViewModel的Item属性换成新的MyObject,这个绑定根本不知道——它还在盯着最初的那个旧实例呢!自然不会更新UI。
而{x:Bind}默认是绑定到ViewModel的属性(比如{x:Bind viewModel.Item.Information}),它会监听ViewModel的PropertyChanged事件,当Item属性更新时,自动切换到新的实例读取Information值,所以UI能正常更新。
解决方案
方案1:修改绑定源为ViewModel,路径指向Item.Information
把绑定的Source改成ViewModel本身,路径设为Item.Information,这样绑定会跟踪ViewModel的Item属性变化,当Item替换成新实例时,自动获取新的Information值:
txtInformation.SetBinding(TextBlock.TextProperty, new Binding() { Mode = BindingMode.OneWay, Source = ViewModel, // 绑定到ViewModel Path = new PropertyPath("Item.Information"), // 路径指向Item的Information属性 TargetNullValue = "No information found" });
方案2:确保MyObject也实现INotifyPropertyChanged(可选)
如果你的场景里,同一个Item实例的Information属性会动态变化(而不是替换整个Item),那还需要让MyObject实现INotifyPropertyChanged,这样当Information更新时,绑定能收到通知:
public class MyObject : INotifyPropertyChanged { private string _information; public string Information { get => _information; set { if (_information != value) { _information = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Information))); } } } public event PropertyChangedEventHandler PropertyChanged; }
这两个方案结合起来,不管是替换Item实例,还是更新Item内部的Information,UI都会正常响应啦~
内容的提问来源于stack exchange,提问作者Marc Cilliers

