【问题标题】:Getting Focused Element in WPF throgh XAML通过 XAML 在 WPF 中获取焦点元素
【发布时间】:2012-05-12 23:46:59
【问题描述】:

我想在屏幕的一个位置显示错误(IDataErrorInfo.Errors),而不是在附近显示错误内容。因此,我已将 textBlock 放在表单的末尾。如何获取当前的焦点元素绑定 (Validation.Errors)[0].ErrorContent.

这应该在 XAML 中而不是在 Code behind 中完成。

当焦点改变时,该元素的错误内容显示在屏幕底部的 TextBlock 中..

感谢和问候 Dineshbabu Sengottian

【问题讨论】:

    标签: wpf idataerrorinfo


    【解决方案1】:

    您可以使用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 错误:17:无法从“(Validation.Errors)”(类型“ReadOnlyObservableCollection`1”)获取“Item[]”值(类型“ValidationError”)。 BindingExpression:Path=(0).(1)[0].ErrorContent; DataItem='MainWindow' (Name='w');目标元素是'TextBlock'(名称='');目标属性是“文本”(类型“字符串”)ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: 指定的参数超出了有效值的范围。

    当当前焦点元素没有验证错误时会出现这些调试错误消息,因为Validation.Errors 数组为空,因此[0] 是非法的。

    您可以选择忽略这些错误消息(示例仍然可以正常运行),或者您仍然需要一些代码隐藏,例如一个转换器,将从FocusManager.FocusedElement 返回的IInputElement 转换为字符串。

    【讨论】:

    • 您好,我有 TextBox 的 ControlTemplate 所以仅适用于 TextBox 它不工作.. 我在 TextBox 的 ControlTemplate 中缺少什么.. 否则它对 PasswordBox 工作正常.. 谢谢..跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 1970-01-01
    相关资源
    最近更新 更多