在WPF中使用BindingExpression的最佳实践?

时间:2013-01-03 20:37:15

标签: c# wpf data-binding mvvm

我有一些UI元素在代码中执行一些特定于UI的工作,然后更新数据上下文中的绑定。

WPF元素:

    <TextBox Grid.Row="1"
             Text="{Binding PartNumber, UpdateSourceTrigger=Explicit}"
             Name="ui_partNumber"
             FontSize="35"
             VerticalContentAlignment="Center" />
    <Button Grid.Column="1"
            Grid.Row="1"
            Content="OK"
            Click="PartOKClick"
            FontSize="20"
            Width="150" />

代码背后:

/// <summary>
/// Handle updating the view model with the part number
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PartOKClick(object sender, RoutedEventArgs e) {

  //Get the textbox's binding expression
  BindingExpression be = ui_partNumber.GetBindingExpression(TextBox.TextProperty);

  if (Condition) {
    //Update part number binding
    be.UpdateSource();

    //Animate to next state
    InAnimate(ui_partGrid.Name);
    OutAnimate(ui_whichPartNumber.Name);
  }
  else {
    //Discard the text in the textbox 
    be.UpdateTarget();

    //Animate to notification state
    InAnimate(ui_invalidLocation.Name);
  }
}

我的ViewModel中的属性如下所示:

public string PartNumber{
    get { return _partNumber; }
    set { _partNumber = value; OnPropertyChanged("PartNumber"); }
}

我正在使用显式绑定,只在事情检查时更新源,否则我只是恢复到原始绑定。

问题是,这是明确使用绑定的最佳方式吗?如果我得到100种不同类型元素的BindingExpression,我是否每次都需要手工完成?我能以更可重复的方式做到这一点吗?

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您愿意检查TextBox中输入的值并仅在有效时更新绑定,对吗?

幸运的是,WPF有一个内置的错误处理过程,比你在那里做的更干净。您应该阅读有关IDataErrorInfo

的内容

This article is pretty clear about how to use it

作为一个例子,你有这样的事情:

WPF元素:

<TextBox Grid.Row="1"
         Text="{Binding PartNumber, ValidatesOnDataErrors=True}"
         Name="ui_partNumber"
         FontSize="35"
         VerticalContentAlignment="Center" />
<Button Grid.Column="1"
        Grid.Row="1"
        Content="OK"
        Click="PartOKClick"
        FontSize="20"
        Width="150" />

ViewModel中,你应该拥有:

public string this[string columnName]
        {
            get
            {
                if (string.Equals(columnName, "PartNumber", StringComparison.OrdinalIgnoreCase) || columnName == string.Empty)
                {
                    // Here, IDataErrorInfo is checking the property "PartNumber" bound to your TextBox
                    if (this.IsPartNumberValid(ui_partNumber.Text))
                    {
                        // Not valid: return any error message (string.Empty = no error, otherwise it will be seen as not valid)
                        return "Not valid!";
                    }
                }
                return string.Empty;
            }
        }

这应该可以解决这个问题:如果字符串“无效!”如果退回,TextBox将显示红色边框,Binding将不会更新

答案 1 :(得分:0)

为什么你被迫使用显式绑定?为什么不在ViewModel中进行验证,然后仅在需要更新时才触发OnPropertyChanged(“BindingParameter”)?

像这样(在VB中):

Property prop as Object
  Get
   return _prop
  End Get 
  Set(ByVal value As Object)
    If your_validation_check(value) then
      _prop = value
      OnPropertyChanged("prop") 'INotifyPropertyChanged
    End If
  End Set 
End Property