2013-04-11 102 views
0

我想完成的是能够验证输入到可编辑组合框中的新类别或从现有组合框列表中选择一个类别。WPF可编辑组合框验证

该验证仅适用于selectedItem,不适用于输入到文本中的新文本。只要我将ValidateOnDataErrors="True"添加到组合框的Text属性,输入新文本的事件就不会触发。类别是Id和Name的简单对象。

XAML:

<Window.Resources> 
    <ControlTemplate x:Key="ValidationErrorTamplate"> 
     <Border BorderBrush="DodgerBlue" BorderThickness="0.75"> 
      <AdornedElementPlaceholder /> 
     </Border> 
    </ControlTemplate> 
    <Style x:Key="ElementInError" TargetType="{x:Type FrameworkElement}"> 
     <Style.Triggers> 
      <Trigger Property="Validation.HasError" Value="True"> 
       <Setter Property="ToolTip" Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 

<ComboBox Name="CbCategory" 
      DisplayMemberPath="Name" 
      IsEditable="True" 
      ItemsSource="{Binding Categories}" 
      SelectedItem="{Binding SelectedCategory, 
           UpdateSourceTrigger=PropertyChanged, 
           ValidatesOnDataErrors=True}" 
      Style="{StaticResource ElementInError}" 
      Text="{Binding NewCategory.Name, 
         UpdateSourceTrigger=PropertyChanged, 
         ValidatesOnDataErrors=True}" 
      Validation.ErrorTemplate="{StaticResource ValidationErrorTamplate}" /> 

视图模型:(: IDataErrorInfo

private Category _newCategory; 
    private Category _selectedCategory; 

    public ExpenseCategory SelectedCategory 
    { 
     get { return _selectedCategory; } 
     set 
      { 
       if (Equals(_selectedCategory, value)) return; 
       _selectedCategory = value; 
       SendPropertyChanged("SelectedCategory"); 
      } 
    } 
    public ExpenseCategory NewExpenseCategory 
    { 
     get { return _newExpenseCategory ?? (_newExpenseCategory = new ExpenseCategory()); } 
      set 
      { 
       if (Equals(_newExpenseCategory, value)) return; 
       _newExpenseCategory = value; 
       SendPropertyChanged("NewExpenseCategory"); 
      } 
     } 

public string this[string propertyName] 
     { 
      get 
      { 
       switch (propertyName) 
       { 
        case "SelectedExpenseCategory": 
        case "NewExpenseCategory": 
         { 
          if ((SelectedCategory == null) || (NewCategory == null) 
          { 
           return "Category must be selected or entered"; 
          } 
         } 
         break; 
       } 
       return string.Empty; 
      } 

回答

1

得到它的工作,它可能是没有高超的方式,但它能够完成任务。

我基本上做了什么,我将NewCategory更改为字符串,而不是类型Category的对象。当用户在组合框中填充新值时,它会根据传入NewCategory构造函数的值启动一个新的SelectedCategory。如果我保留对象类型Category的NewCategory,它不起作用。

public string NewExpenseCategory 
    { 
     get { return _newExpenseCategory ?? (_newExpenseCategory = ""); } 
     set 
     { 
      if (Equals(_newExpenseCategory, value)) 
       return; 
      _newExpenseCategory = value; 
      SendPropertyChanged("NewExpenseCategory"); 
      SelectedExpenseCategory = new ExpenseCategory 
       { 
        Name = value 
       }; 
     } 
    } 

    public string this[string propertyName] 
    { 
     get 
     { 
      switch (propertyName) 
      { 
       case "SelectedExpenseCategory": 
       case "NewExpenseCategory": 
        { 
         if ((SelectedExpenseCategory.Name.Length == 0) && (NewExpenseCategory.Length == 0)) 
         { 
          return "Category must be selected or entered"; 
         } 
        } 
        break; 
      } 
      return string.Empty; 
     } 
    } 
+0

当我尝试在“我的组件”的组合框中输入新值时,我总是收到一个空错误。关心提供当前的项目代码以及你所拥有的?它在我的行上失败,等于你的(SelectedExpenseCategory.Name.Length == 0) – JTester 2014-12-20 07:38:22