我有问题: 我在窗体上有一些控件(复选框,组合框,滑块,文本框)。它们的值绑定到视图模型的不同属性 当视图模型的属性具有特定值时,I 希望这些控件“固定”(显示错误信息并将它们设置为某个固定值(例如:当用户尝试检查时,复选框未选中,滑块设置为某个值,组合的选定项目是列表中的第二项)。 我是这样做的(文本框的简化示例): 在视图中:
<TextBox
Text="{Binding ViewModelProperty,
NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
/>
在视图模型中: 该属性定义如下:
String _ViewModelProperty;
public String ViewModelProperty
{
get
{
return _ViewModelProperty;
}
set
{
_ViewModelProperty = value;
OnPropertyChanged("ViewModelProperty");
}
}
和IDataErrorInfo的实现:
String IDataErrorInfo.this[String propertyName]
{
get
{
String error = null;
if (propertyName == "ViewModelProperty")
{
if (ViewModelProperty != "FixedValue")
{
error = DisplayMessage("You can only set a fixed value here");
ViewModelProperty= "FixedValue";
}
}
return error;
}
}
这适用于复选框,但对于所有其他控件,它的功能如下:用户设置“错误”值,显示错误消息然后,而不是使用固定值更新控件,仍然显示错误的值(它不再与视图模型同步)。
我无法弄清楚如何强制更新控件的值。
提前谢谢。
答案 0 :(得分:0)
您可以将要修复的控件的IsEnabled属性绑定到ViewModel上的一组属性,例如CanUserChangeSlider。
<Slider IsEnabled={Binding CanUserChangeSlider} ... />
所以在Comboboxes绑定属性的setter中:
set
{
// store value in backing store
// RaisePropertyChanged
if (value == true)
{
this.CanUserChangeSlider = false;
// the bound property for slider set to certain value
// the bound property for combobox changed to be a certain value
}
}
答案 1 :(得分:0)
强制重新绑定的方法是根据需要调用BindingExpression.UpdateTarget()
或BindingExpression.UpdateSource()
。
当然,您不希望在视图模型中使用它。
由于我将视图模型注入到视图中,并在视图构造函数中将它们设置为DataContext
,因此我会执行以下操作:
Dispose()
并删除处理程序)基本上,只要在强制数据时引发事件,并传递视图需要重新绑定到视图模型的数据。
这是我的头脑,所以我还没有确定委托签名中可能需要的确切参数,也没有计算处理程序与所有字段一起使用的程度。不过,这可能是一个起点。
答案 2 :(得分:0)
我不使用IsEnabled属性,因为这些是要求:没有禁用,只有在设置“无效”值时才显示消息。
其他要求不是将视图模型注入到视图中......我们有一些“工作空间”类将视图与视图模型链接起来,因此没有视图知道附加到它的视图模型实例。当然,可以从工作区进行注射......我试过这个并且似乎仍然不起作用
但这不是任何其他优雅和MVVM-ish方法吗?
我准备了一个非常简单的例子来说明我的问题
我有2个文本框,绑定到视图模型中的相同属性:
<StackPanel>
<Label>First text box</Label>
<TextBox
Text="{Binding Path=Property,
NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
/>
<Label>Second text box</Label>
<TextBox
Text="{Binding Path=Property,
NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
/>
</StackPanel>
视图模型具有IDataErrorInfo实现:
public String this[String propertyName]
{
get
{
String error = null;
if (propertyName == "Property")
{
if (Property != "1000")
{
error ="Only value '1000' is accepted here.";
MessageBox.Show(error, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
Property = "1000";
}
}
return error;
}
}
最初,值为“1000”
如果我在一个文本框中添加“0”,则显示消息,另一个文本框正确更新为“1000”,但聚焦文本框的值仍为“10000”。
我觉得我在这里想念一些必要的东西。
露西亚