WPF - 在ItemsControl中以编程方式创建控件验证

时间:2014-10-29 15:46:02

标签: c# wpf validation xaml combobox

我在WPF代码中遇到了奇怪的问题。我有一个组合框,允许用户选择其中一个选项。此组合框中的每个项目都是某种string.Format()模式。例如,当用户选择选项'Hello {0} world'时,我的代码会生成两个TextBlocks 'Hello''world'以及一个TextBox,用户可以在其中提供输入。

这是我的xaml:

<ComboBox ItemsSource="{Binding PossiblePatternOptions}" DisplayMemberPath="Pattern" SelectedItem="{Binding SelectedPattern, ValidatesOnDataErrors=True}" Width="250" Margin="5,0,25,0"/>
<ItemsControl ItemsSource="{Binding SelectedPattern.GeneratedControls}"/>

SelectedPattern.GeneratedControlsObservableCollection<UIElement>

public ObservableCollection<UIElement> GeneratedControls
{
   get
   {
      return _generatedControls ?? (_generateControls = new ObservableCollection<UIElement>(GenerateControls(_splittedPattern)));
   }
}

以下是我创建新TextBox(在GenerateControls方法中)的方法:

var placeholderChunk = chunk as TextBoxPlaceholder;
var textBox = new TextBox();
textBox.ToolTip = placeholderChunk.Description;

Binding binding = new Binding("Value");
binding.ValidatesOnDataErrors = true;

binding.Source = placeholderChunk;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
textBox.SetBinding(TextBox.TextProperty, binding);

TextBoxPlaceholder实现IDataErrorInfo并提供错误输入的错误详细信息:

public class TextBoxPlaceholder : IDataErrorInfo
{
   public string Value {get;set;}

   public string this[string columnName]
   {
      get
      {
         switch (columnName)
         {
            case "Value":
            return string.IsNullOrEmpty(Value) ? "Error" : string.Empty;

            default:
            return string.Empty;
         }
      }
    }

   public string Error
   {
      get { throw new NotImplementedException(); }
   }
}

问题在于,当我第一次从组合框中选择一个选项时,生成的TextBoxes被正确验证并且它们周围会出现漂亮的红框,但是当我选择之前选择的选项时,没有验证发生,不再有红框。我注意到当我更改GeneratedControls属性中的代码以便每次都重新创建集合时,它可以正常工作。这可能是什么问题?

我知道可能会解释得很糟糕,如果有任何误解,我会澄清。

1 个答案:

答案 0 :(得分:0)

看起来你的价值&#34;属性在更改时不会触发更新,因此文本框的文本绑定无法对更改做出反应,也不会再次评估该值。尝试这样的事情:

// implmeent INotifyPropertyChanged
public class TextBoxPlaceholder : IDataErrorInfo, System.ComponentModel.INotifyPropertyChanged
{
    private string mValue;

    public string Value 
    {
        get{ return mValue; }
        // fire notification
        set{mValue = value;NotifyPropertyChanged("Value");}
    }

    public event PropertyChangedEventHandler PropertyChanged;

    // helper method
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    // your code goes here