我将以下课程作为DataContext
的{{1}}:
UserControl
我将public class ModelBase<T> : INotifyPropertyChanged where T : class
{
public T Model { get; set; }
public void UpdateUI()
{
OnPropertyChanged(string.Empty);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
设置为包含基本类型的任意类。
我似乎正确地完成了绑定,因为我可以看到在UI中更改属性时正在填充属性。
但问题是,当我从后面的代码更改属性时,即使在调用Model
之后,它也不会使用它来更新视图。我验证了UI的UpdateUI()
中的属性(使用WPF / XAML检查软件),它们具有正确的值。
我认为它与DataContext
中的嵌套类这一事实有关,因为我尝试向DataContext
添加属性来测试它,并且绑定工作正常我打电话给ModelBase
。
我正在创建控件/绑定并将其添加到后面代码中的UpdateUI()
,我不确定这是否会导致问题:
UserControl
答案 0 :(得分:1)
要TwoWay
绑定,您必须具备以下条件:
支持字段
setter引发属性更改的公共属性 通知。
实现INotifyPropertyChanged
接口或继承的模型
来自实现它的类
这是一个很好的方法:
重写您的ModelBase
(基于Implementing INotifyPropertyChanged - does a better way exist?):
public class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
//make sure we fire the event only when newvalue!=oldvalue
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
并将其用作
class Model:ModelBase{
//example for a property that is appropriate for 2 way bidning
private string _prop;
public string prop{
get{return _prop;}
set{SetField(ref _prop,value);}
}
}
如果这还不够,请解释原因。
更新:根据您的需要,您几乎可以按照自己的方式进行操作,但只是您没有正确指定PropertyPath,它应该是"Model."+nameOfProperty
并注意到您除非您的容器Source = myModelBase
未设置为DataContext
,否则不需要设置var binding = new Binding
{
Path = new PropertyPath("Model."+nameOfProperty),
Mode = BindingMode.Default,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
。
所以:
var binding = new Binding
{
Source = myModelBase,
Path = new PropertyPath("Model."+nameOfProperty),
Mode = BindingMode.Default,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
或者:
{{1}}
不确定这是否有效,但可能是问题,否则你的想法很好。