搜索并没有给我任何线索,我有点茫然。 到目前为止,WPF都是自学的,所以我可能忽略了一些简单的事情。
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<TextBlock Text={Binding BoundTextProperty}"/>
这是简化的xml
public class MainViewModel
{
private Model Data;
public MainViewModel()
{...}
public string BoundTextProperty => Data.BoundTextProperty;
...
}
绑定的属性引用了模型中包含数据的属性
public class Model : INotifyPropertyChanged
{
private long number;
public long Number
{
get { return number; }
set
{
number = value;
OnPropertyChanged(nameof(BoundTextProperty));
}
}
public string BoundTextProperty => $"Some text {Number} some text again";
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我发誓它在某些时候有效。 该字符串还有两个其他变量,但这是它工作或不工作的基础。
我的问题是,绑定实际上是否可以冒泡,如果可以,为什么不呢?
答案 0 :(得分:1)
您必须添加用于将Model的PropertyChanged事件从ViewModel冒泡到View的代码。 这是一个示例(基于您的代码):
public class MainViewModel : ViewModelBase
{
private readonly Model Data;
public MainViewModel()
{
Data = new Model();
Data.PropertyChanged += ModelOnPropertyChanged;
}
private void ModelOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(Model.BoundTextProperty):
OnPropertyChanged(nameof(MainViewModel.BoundTextProperty));
break;
// add cases for other properties here:
}
}
public string BoundTextProperty => Data.BoundTextProperty;
}
public class Model : ModelBase
{
private long number;
public long Number
{
get { return number; }
set
{
number = value;
OnPropertyChanged(nameof(BoundTextProperty));
}
}
public string BoundTextProperty => $"Some text {Number} some text again";
}
public abstract class ViewModelBase : Base
{
// add other ViewModel related stuff here
}
public abstract class ModelBase : Base
{
// add other Model related stuff here
}
public abstract class Base : INotifyPropertyChanged
{
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
答案 1 :(得分:1)
您需要为XAML中绑定的源属性引发PropertyChanged
事件。在这种情况下,您绑定到BoundTextProperty
的{{1}},这意味着MainViewModel
类应该引发MainViewModel
事件。
source属性是否包装确实引发PropertyChanged
事件的类的另一个属性都没有关系。通知视图的是绑定的源对象。
如果您将PropertyChanged
转换为视图模型中的公共属性,则也可以直接绑定到“ model”属性:
Data
如果您选择坚持使用wrapper属性,则无论何时更新模型,public Model Data { get; private set; }
...
<TextBlock Text="{Binding Data.BoundTextProperty}"/>
必须实现MainViewModel
事件并引发INotifyPropertyChanged
事件:
PropertyChanged