WPF使用和AccessText类的预期结果

10

今天我正在学习AccessText类。我无法确定使用这个类的确切用途和结果。

如果你在一个标签(Label)中使用AccessText并将Target属性设置为一个TextBox,那么当按下访问键时,TextBox将获得焦点。请参见下面的代码:

<StackPanel>
    <Label Target="{Binding ElementName=txtbox}">
        <AccessText>_first_second</AccessText>
    </Label>
    <TextBox Name="txtbox" Width="100" Height="50"/>
</StackPanel>

如果您在使用Label的同时,将AccessText与一个目标属性为ButtonButton一起使用,那么当按下访问键时,ButtonClick事件将被执行。

那么我的问题是:

1. AccessText类的确切行为是什么?如果我要预测它与其他类型控件(如DataGridComboBoxRadioButton)一起使用时的效果,如何确定预期结果?

2. 为什么该类源自FrameworkElement?作为FrameworkElement,它有哪些应用程序?似乎不只是为了指定访问键等功能。

1个回答

13

AccessText是一个FrameworkElement,它的行为基本上类似于一种特殊类型的TextBlock,允许单个下划线(_)后面的任何键盘字符作为访问键。

对于给定的控件,关联访问键的行为取决于其OnAccessKey方法。 OnAccessKeyUIElement的虚拟方法,它提供以下定义:

protected virtual void OnAccessKey(AccessKeyEventArgs e)
{
    this.Focus();
}

因此,任何不覆盖由UIElement定义的OnAccessKey的控件都将保留默认行为,即在按下访问键时将控件带入焦点。

Button继承自ButtonBaseButtonBaseOnAccessKey有以下定义:

protected override void OnAccessKey(AccessKeyEventArgs e)
{
    if (e.IsMultiple)
        base.OnAccessKey(e);
    else
        this.OnClick();
}

如果IsMultiple为true,则Button和其他继承自ButtonBase的控件的默认行为将是将控件置于焦点,否则,它会引发单击事件(如果与多个UIElement关联一个访问键,则IsMultiple为真)。

鉴于此背景,以下是针对您具体问题的答案:

  1. 作为控件的ContentPresenter使用时,AccessText元素的明确定义行为是将在单个下划线后面注册第一个字母到AccessKeyManager,当按下该键时,将调用控件的OnAccessKey方法。了解这将对特定控件做什么需要知道该控件所使用的OnAccessKey的定义方式。如果在其继承链中没有重写,则按访问键将使控件获得焦点。如果有一个重写,则行为将取决于重写方法的定义。可以通过实验、阅读相关文档或检查源代码来确定这一点。

  2. AccessText之所以是FrameworkElementTextBlock相同的原因是因为它有一个视觉形式,并且占用布局系统在定位其他元素时需要考虑的空间。此外,FrameworkElements允许进行样式设置,并且具有自己的DataContext属性,这允许绑定方案,否则将不可能实现。如果AccessText不是FrameworkElement,那么它将是不必要的限制,并且会阻止WPF开发人员可能具有的合理(尽管可能很少见)用例。

编辑

以下是一个漂亮的电源按钮示例,展示了AccessText作为FrameworkElement的有用性:

<Grid>
    <Button Width="150"
            Height="35"
            Command="{Binding PowerCommand}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Status" />
            <Rectangle Margin="5,2,0,0"
                       Width="10"
                       Height="10"
                       Fill="{Binding PowerFill}" />
            <AccessText Margin="25,0,0,0"
                        Text="{Binding PowerText}" />
        </StackPanel>
    </Button>
</Grid>

这将导致(按下Alt后):

enter image description here

点击按钮或按下Alt+S后,视图模型会响应该命令并更改TextFill,从而导致以下结果:

enter image description here

再次单击或使用访问键将返回到第一状态。


@KyloRen,我尝试更详细地阐述答案#2。 - devuxer
WPF开发人员可能需要在AccessText类中绑定什么? - Kylo Ren
2
WPF开发人员在AccessText类中可能需要绑定什么?肯定是“Text”属性,可能还有像“Margin”,“Foreground”,“FontWeight”和“FontStyle”这样的东西。我知道我可以为AccessText类设置布局,但是否真的需要呢?我会添加一个示例。我确实听到您说,专门为此目的添加一个特殊的“FrameworkElement”是一种奇怪的设计选择。我不确定为什么他们没有只是在“TextBlock”中添加一个“RecognizesAccessKey”属性并结束。 - devuxer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接