2013-02-19 7 views
6

Jak uzyskać szablon błędu WPF, aby pojawił się w formancie kontrolki UserControl w WPF?Pokaż szablon błędu sprawdzania poprawności dla elementów sterujących w sterowniku UserControl w WPF

Mam UserControl zawierający dwie etykiety, dwa pola tekstowe i CheckBox. Jeden z pól tekstowych reprezentuje nazwę encji i jest powiązany z właściwością Nazwa poza właściwością Model wyeksponowaną przez mój ViewModel, który jest DataContext mojego okna. Klasa Model implementuje interfejs IDataErrorInfo i potwierdziłem poprzez Testowanie Jednostek, że gdy Nazwa jest pusta, błąd jest zwracany przez implementację indeksera właściwości. Powiązałem się z właściwością Dependency wspierającą Name TextBox w moim UserControl i gdy napotkano błąd sprawdzania poprawności szablon błędu WPF umieszcza czerwone obramowanie wokół całego UserControl, a nie tylko Name TextBox.

Wiązanie z polem nazwy UserControl jest następujące.

<vc:MyUserControl ItemName="{Binding Model.Name, ValidatesOnDataErrors=True}" /> 

Moja wersja UserControl z uproszczoną wersją i wersją DependencyProperty wygląda następująco.

<UserControl> 
    <Grid> 
     <TextBox Text="{Binding ItemName}" /> 
    </Grid> 
</UserControl> 

public partial class MyUserControl: UserControl 
{ 
    public static readonly DependencyProperty ItemNameProperty = 
     DependencyProperty.Register(
      "ItemName", 
      typeof(string), 
      typeof(MyUserControl), 
      new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault) 
    ); 

    public string ItemName 
    { 
     get { return (string)GetValue(ItemNameProperty); } 
     set { SetValue(ItemNameProperty, value); } 
    } 
} 

Informacje Znalazłem odnoszące się do tej kwestii do tej pory wszystko było w odniesieniu do Silverlight lub za pomocą konwertera, aby nie pokazać czerwoną granicę (która nie ma sensu dla mnie). Ta informacja została znaleziona tutaj na stackoverflow.

Ktoś był w stanie rozwiązać ten problem z WPF? Czy przeoczyłem coś oczywistego?

+0

pokrewne pytanie [tutaj] (http://stackoverflow.com/q/7808986/620360) i [tutaj] (http://stackoverflow.com/q/1198342/620360) – LPL

+0

Dzięki LPL. Podczas moich badań nad tym zagadnieniem widziałem oba te pytania. Przyjęta odpowiedź na drugi link to użycie konwertera, do którego się odwoływałem w moim pytaniu. Wydaje mi się to całkiem błędne. Przyjęta odpowiedź w pierwszym pytaniu również nie sprawdziła się u mnie. – CoderDawson

Odpowiedz

9

Zostanie użyty ErrorTemplate dla UserControl, jeśli powiązania z Twoim UserControl wykorzystają ValidatesOnDataErrors=True. Ale możesz usunąć czerwoną granicę za pomocą Validation.ErrorTemplate Attached Property.

Wszystkie elementy sterujące w obrębie twojego UserControl będą wyświetlać czerwoną ramkę tylko wtedy, gdy sprawdzimy ich powiązania, implementując IDataErrorInfo również w przypadku zależności DependencyProperties.

public class MyUserControl : UserControl, IDataErrorInfo 
{ 
    public static readonly DependencyProperty ItemNameProperty = 
     DependencyProperty.Register(
      "ItemName", 
      typeof(string), 
      typeof(MyUserControl), 
      new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault) 
    ); 

    public string ItemName 
    { 
     get { return (string)GetValue(ItemNameProperty); } 
     set { SetValue(ItemNameProperty, value); } 
    } 

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

    public string this[string columnName] 
    { 
     get 
     { 
     // use a specific validation or ask for UserControl Validation Error 
     return Validation.GetHasError(this) ? "UserControl has Error" : null; 
     } 
    } 
} 

a tu uproszczona XAML

<UserControl Validation.ErrorTemplate="{x:Null}"> 
    <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"> 
     <TextBox Text="{Binding ItemName, ValidatesOnDataErrors=True}" /> 
    </Grid> 
</UserControl> 

Dodawanie

Jeśli chcesz rozróżniać błędy można uzyskać BindingExpression dla DependencyProperty i sprawdź HasError Property.

BindingExpression be = BindingOperations.GetBindingExpression(this, ItemNameProperty); 
return be != null && be.HasError ? "ItemName has Error" : null; 
+0

Jeszcze raz dziękuję LPL. Pierwotnie próbowałem podobną zmianę, ale nie byłem w stanie określić, który z TextBoxów wewnątrz UserControl miał błąd, ponieważ wywołanie Validation.GetHasError w samym TextBox zawsze zwróciło fałsz. Z dwóch pól TextBox w moim UserControl jest tak czy inaczej, aby określić, które pole rzeczywiście ma błąd? – CoderDawson

+0

Nie jestem pewien, co wcześniej zrobiłem źle, ale to wydaje się działać dla mnie. Nadal nie widzę sposobu rozróżniania błędów w unikatowych TextBoxach, ale w tym momencie będę mieć tylko walidację na jednym z nich. Dzięki, LPL! – CoderDawson

+1

Dodałem sugestię rozróżniania błędów. ;) – LPL

Powiązane problemy