wpf控件:如何通过绑定强制值始终有效?

时间:2011-06-08 15:40:45

标签: wpf binding inotifypropertychanged

我有一组控件,其中某个值始终有效,但其他控件有效或无效,具体取决于某些逻辑。该逻辑的设计方式使其永远无法使自身无效:在使用无效参数调用logic.SetState(...)时,它将返回false并生成错误消息,但它的内部结构不会受到影响。换句话说,它的状态没有变化。我希望这能反映在屏幕上,但无法弄清楚代码有什么问题。

这是我想用ComboBox实现的一个例子,但这同样适用于一组复选框甚至文本框,即任何控制用户输入。 XAML:

<ComboBox ItemsSource="{Binding Path=States}"
          SelectedItem="{Binding Path=State}"/>

代码:

public string State
{
  get { return state; }
  set
  {
    if( value != "invalid" )
      state = value;
    else
      ShowError(); //tell user this selection was not ok
    RaisePropertyChanged( "State" ); //the usual INotifyPropertyChanged method
  }
}

public string[] States
{
  get { return new string[] { "none", "valid", "invalid" }; }
}

private string state;

State的初始值设置为“none”。当用户选择“有效”时,状态成员将设置为新值并发布属性更改。

当用户选择“无效”时,状态成员不会更改,但组合框显示“无效”。因此,屏幕上的内容(“无效”)与应用程序中使用的有效值(“有效”)之间存在不匹配,我宁愿避免这种情况。

  1. 我不明白为什么ComboBox仍然显示“无效”:我认为通过调用RaisePropertyChanged(“State”)会触发ComboBox以获取State的值并显示它,特此设置ComboBox再次“有效”?

  2. 有没有办法做到这一点?请注意,代码位于ViewModel样式的类中,该类不了解ComboBox。

  3. 更好的做法是不这样做,而是依靠'正常'验证方法?例如,我可以实现IDataErrorInfo并显示一条消息,告诉用户当前显示的值无效,在它周围显示一个红色框等。同时我还必须禁用几乎所有其他控件,直到这一个控件再次有效(因为应用程序的其他部分将使用随后显示在屏幕上的其他值,结果可能非常意外)。

1 个答案:

答案 0 :(得分:1)

当UI调用setter时,将忽略引发PropertyChanged事件。有一个已知的工作,如果您在绑定上有一个转换器,它正确处理PropertyChange。解决方案是创建一个只返回传入值的虚拟转换器。请参阅本文,了解如何执行此操作:

http://www.lhotka.net/weblog/DataBindingIssueInWPFWithSolution.aspx

要回答列表中的问题3,是的,这是我通常采用的方法。永远不要将用户值更改回某些东西,而是显示错误并让他们将其更改回来。