2012-05-12 1 views
3

Я хочу отображать ошибки (IDataErrorInfo.Errors) в одном месте экрана, а не показывать содержимое ошибки рядом. Итак, для этого я разместил textBlock в конце формы .. Как Могу ли я получить текущий фокусированный элемент для привязки (Validation.Errors) [0] .ErrorContent.Получение фокусированного элемента в WPF throgh XAML

Это должно быть сделано в XAML, а не в коде.

Когда фокус изменился, тем содержание ошибки этого элемента отображаются в том, что TextBlock помещенных в нижней части экрана ..

Благодаря & уважение Dineshbabu Sengottian

ответ

3

Вы можете получить доступ к целенаправленному элементу, используя FocusManager.FocusedElement. Вот пример, который работает исключительно с XAML, без какого-либо кода позади (за исключением, конечно отделенного кода, необходимого для обеспечения IDataErrorInfo ошибок для тестирования):

<Window x:Class="ValidationTest.MainWindow" 
     x:Name="w" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 

    <StackPanel> 
     <TextBox x:Name="txt1" Text="{Binding Path=Value1, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, Mode=TwoWay}"/> 
     <TextBox x:Name="txt2" Text="{Binding Path=Value2, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, Mode=TwoWay}"/> 
     <TextBlock Foreground="Red" Text="{Binding 
         RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, 
         Path=(FocusManager.FocusedElement).(Validation.Errors)[0].ErrorContent}"/> 
    </StackPanel> 
</Window> 

Тест класс MainWindow имеет следующий код:

namespace ValidationTest 
{ 
    public partial class MainWindow : Window, IDataErrorInfo 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      DataContext = this; 

      Value1 = "a"; 
      Value2 = "b"; 
     } 

     public string Value1 { get; set; } 
     public string Value2 { get; set; } 

     #region IDataErrorInfo Members 

     public string Error 
     { 
      get { return ""; } 
     } 

     public string this[string name] 
     { 
      get 
      { 
       if (name == "Value1" && Value1 == "x") 
       { 
        return "Value 1 must not be x"; 
       } 
       else if (name == "Value2" && Value2 == "y") 
       { 
        return "Value 2 must not be y"; 
       } 
       return ""; 
      } 
     } 

     #endregion 
    } 
} 

Для тестирования вы получите ошибку проверки, если вы положили «x» в первом текстовом поле или если вы положили «y» во второе текстовое поле.

Сообщение об ошибке текущего сфокусированного текстового поля появляется под двумя текстовыми полями в TextBlock.

Обратите внимание, что это решение имеет один недостаток. Если запустить образец под отладчиком, вы увидите эти ошибки связывания: возникают

System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'ValidationError') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1'). BindingExpression:Path=(0).(1)[0].ErrorContent; DataItem='MainWindow' (Name='w'); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.

Эти сообщения отладки ошибок, когда в данный момент сосредоточен элемент не имеет ошибки проверки, поскольку Validation.Errors массив пуст, и, следовательно, [0] является незаконным ,

Вы можете либо игнорировать эти сообщения об ошибках (образец все еще работает нормально), либо вам нужен какой-то код, тем не менее, например. конвертер, который преобразует IInputElement, возвращенный с FocusManager.FocusedElement в строку.

+0

Привет, у меня есть ControlTemplate для TextBox. Так что для TextBox только это не работает. Это что-то мне не хватает в ControlTemplate из TextBox .. В противном случае это работает отлично для PasswordBox .. Спасибо .. – dinesh