2012-08-26 40 views
3

編輯控件:發現,我在這裏工作的解決方案: http://social.msdn.microsoft.com/Forums/en/wpf/thread/c1fd21b2-424b-4536-be8c-335cee94596aValidationRules對內部用戶控件

如下:

private void TextBoxLoaded(object sender, RoutedEventArgs e) 
    { 
     Binding bd = new Binding(TextBoxText.ToString()); 
     bd.ValidationRules.Add(new DataErrorValidationRule()); 
     bd.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
     TextBox tb = sender as TextBox; 
     tb.SetBinding(TextBox.TextProperty, bd); 
    } 

<UserControl x:Class="WpfApplication1.UserControl1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:wa="clr-namespace:WpfApplication1" 
     mc:Ignorable="d"> 
<DockPanel 
    VerticalAlignment="Center"> 
    <Label 
     VerticalAlignment="Center" 
     Content="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type wa:UserControl1}},Path=LabelContent}"/> 
    <TextBox 
     VerticalAlignment="Center" 
     MinWidth="96" 
     Loaded="TextBoxLoaded"> 
    </TextBox> 
</DockPanel> 

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:wa="clr-namespace:WpfApplication1" 
    Title="MainWindow"> 
<Window.Resources> 
    <DataTemplate x:Key="personDisplay"> 
     <DockPanel> 
      <wa:UserControl1 LabelContent="First name:" TextBoxText="fname"/> 
      <wa:UserControl1 LabelContent="Last name:" TextBoxText="lname"/> 
      <wa:UserControl1 LabelContent="Age:" TextBoxText="age"/> 
     </DockPanel> 
    </DataTemplate> 
</Window.Resources> 
<ContentControl 
    VerticalAlignment="Center" 
    Name="personCcl" 
    ContentTemplate="{StaticResource personDisplay}"/> 

END

我有一個需要包含一個標籤和一個文本框和文本框條目的用戶控件需要有檢查輸入的值是無效的有效性規則。我有一個數據模式,顯示使用usercontrol具有多個字段的類。該類實現了IDataErrorInfo。但是,我遇到的問題是,文本框不訪問類IDataErrorInfo,此外,圍繞無效控件的紅色輪廓圍繞整個用戶控件,而不僅僅是用戶控件中的文本框。

我已經創建了一個更簡單的例子,我在下面嘗試做什麼。

下面是類

public class Person : IDataErrorInfo 
{ 
    public string fname { get; set; } 
    public string lname { get; set; } 
    public int age { get; set; } 

    public Person(string f, string l, int a) 
    { 
     fname = f; 
     lname = l; 
     age = a; 
    } 
    public string Error 
    { 
     get 
     { 
      if (age < 18) return "Too young"; 
      else if (fname == null || fname.Length == 0) return "Needs first name"; 
      else if (lname == null || lname.Length == 0) return "Needs last name"; 
      return null; 
     } 
    } 
    public string this[string name] 
    { 
     get 
     { 
      if (name == "age") { return age < 18 ? "Too young" : null; } 
      else if (name == "fname") { return fname == null || fname.Length == 0 ? "Needs first name" : null ; } 
      else if (name == "lname") { return lname == null || lname.Length == 0 ? "Needs last name" : null; } 
      return null; 
     } 
    } 
} 

這裏是用戶控件:

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 
    static readonly public DependencyProperty LabelContentProperty = DependencyProperty.Register(
     "LabelContent", 
     typeof(string), 
     typeof(UserControl1), 
     new FrameworkPropertyMetadata("") 
    ); 
    public string LabelContent 
    { 
     get { return GetValue(LabelContentProperty) as string; } 
     set { SetValue(LabelContentProperty, value); } 
    } 
    static readonly public DependencyProperty TextBoxTextProperty = DependencyProperty.Register(
     "TextBoxText", 
     typeof(object), 
     typeof(UserControl1), 
     new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnTextBoxTextChanged), new CoerceValueCallback(CoerceTextBoxText)) 
    ); 
    public object TextBoxText 
    { 
     get { return GetValue(TextBoxTextProperty); } 
     set { SetValue(TextBoxTextProperty, value); } 
    } 
    static private void OnTextBoxTextChanged(DependencyObject dob, DependencyPropertyChangedEventArgs ea) 
    { 
     var uc = dob as UserControl1; 
     uc.OnTextBoxTextChanged(new RoutedPropertyChangedEventArgs<object>(ea.OldValue, ea.NewValue, TextBoxTextChangedEvent)); 
    } 
    static private object CoerceTextBoxText(DependencyObject dob, object o) 
    { 
     return o; 
    } 
    static readonly public RoutedEvent TextBoxTextChangedEvent = EventManager.RegisterRoutedEvent(
     "TextBoxTextChanged", 
     RoutingStrategy.Bubble, 
     typeof(RoutedPropertyChangedEventArgs<object>), 
     typeof(UserControl1)); 
    public event RoutedPropertyChangedEventHandler<object> TextBoxTextChanged 
    { 
     add { AddHandler(TextBoxTextChangedEvent, value); } 
     remove { RemoveHandler(TextBoxTextChangedEvent, value); } 
    } 
    protected virtual void OnTextBoxTextChanged(RoutedPropertyChangedEventArgs<object> ea) { RaiseEvent(ea); } 
} 

下面是用戶控件XAML:

<UserControl x:Class="WpfApplication1.UserControl1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:wa="clr-namespace:WpfApplication1" 
     mc:Ignorable="d"> 
<DockPanel> 
    <Label 
     VerticalAlignment="Center" 
     Content="{Binding RelativeSource={RelativeSource FindAncestor, 
      AncestorType={x:Type wa:UserControl1}}, 
     Path=LabelContent}"/> 
    <TextBox 
     VerticalAlignment="Center" 
     MinWidth="96"> 
     <TextBox.Text> 
      <Binding 
        RelativeSource="{RelativeSource FindAncestor, 
         AncestorType={x:Type wa:UserControl1}}" 
        Path="TextBoxText" 
        Mode="TwoWay" 
        UpdateSourceTrigger="PropertyChanged"> 
       <Binding.ValidationRules> 
        <DataErrorValidationRule ValidatesOnTargetUpdated="True"/> 
       </Binding.ValidationRules> 
      </Binding> 
     </TextBox.Text> 
    </TextBox> 
</DockPanel> 

這裏是窗口XAML(更新) :

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:wa="clr-namespace:WpfApplication1" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="personDisplay"> 
     <DockPanel> 
      <wa:UserControl1 LabelContent="First name:" TextBoxText="{Binding fname,Mode=TwoWay}"/> 
      <wa:UserControl1 LabelContent="Last name:" TextBoxText="{Binding lname,Mode=TwoWay}"/> 
      <wa:UserControl1 LabelContent="Age:" TextBoxText="{Binding age,Mode=TwoWay}"/> 
     </DockPanel> 
    </DataTemplate> 
</Window.Resources> 
<ContentControl 
    VerticalAlignment="Center" 
    Name="personCcl" 
    ContentTemplate="{StaticResource personDisplay}"/> 
</Window> 

這裏是窗口構造

public MainWindow() 
{ 
    InitializeComponent(); 
    personCcl.Content = new Person("John", "Smith", 33); 
} 
+0

如果我錯了,請告訴我。你想爲你的TextBox進行驗證並將它的DataContext設置爲ViewModel來啓動驗證?我不確定你在這裏試圖實現什麼 –

+0

我還是新來的wpf,所以我無法正確表達所有的術語。例如,在上面的代碼中,在保存年齡值的文本框中,如果我鍵入15,它應該轉到person類並檢查驗證規則並確定「太年輕」。這雖然沒有發生。看起來正在發生的是,文本框的綁定只是一個被驗證的字符串。我想驗證發生在person類的IDataErrorInfo上,但它只適用於特定的文本框而不是整個用戶控件。希望能幫助解釋一些事情。 – uc71

+0

您是否將ContentControl的DataContext設置爲您的Person類? –

回答

1

這是不對的。不要讓personCc1.Content =新人。使其成爲personCc1.DataContext =新人。內容期望您只顯示該類的值,並且主要用於UI。

+0

Ahh ok。當我有機會時我會嘗試。謝謝。 – uc71