Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF uses and expected results of AccessText class

I was going through the class AccessText today. I couldn't identify exact use and results of using this class.

If you use AccessText with a Label and use Target property as a TextBox, the TextBox will get focus when access key is pressed.see below code:

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

If you use AccessText with a Label and use Target property as a Buton , the Button Click event will get executed when access key is pressed.

So my questions are

1.what is the definitive behavior of AccessText Class? If I have to predict it's uses with other type of controls like DataGrid, ComboBox, RadioButton? how can i be sure of expected result?

2.Why is this class derived from FrameworkElement? What applications does it have as a FrameworkElement? seems a bit more for just specifying Accesskeys etc.

like image 940
Kylo Ren Avatar asked Feb 21 '16 09:02

Kylo Ren


1 Answers

AccessText is a FrameworkElement that acts more or less like a special type of TextBlock that allows any keyboard character following a single underscore (_) to act as an access key.

For a given control, the behavior of associated access keys depends on its OnAccessKey method. OnAccessKey is a virtual method of UIElement, which provides the following definition:

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

So, any control that doesn't override the definition of OnAccessKey defined by UIElement will maintain the default behavior, which is for the control to be brought into focus when the access key is pressed.

ButtonBase, which Button inherits from, has the following definition for OnAccessKey:

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

So the default behavior of Button and other controls that inherit from ButtonBase will be to bring the control into focus if IsMultiple is true, otherwise, it will raise the click event. (IsMultiple is true if an access key is associated with more than one UIElement.)

With this background in mind, here are the answers to your specific questions:

  1. The definitive behavior of an AccessText element used as a control's ContentPresenter is to register the first letter following a single underscore with the AccessKeyManager, which will invoke the control's OnAccessKey method when the key is pressed. Knowing what this will do for a particular control requires knowing which definition of OnAccessKey is in force for that control. If there are no overrides in its inheritance chain, pressing the access key will bring the control into focus. If there is an override, the behavior will depend on the overriding method's definition. This can be determined via experimentation, reading relevant documentation, or examining the source code.

  2. AccessText is a FrameworkElement for the same reasons that TextBlock is a FrameworkElement. It has a visual form and takes up space that the layout system needs to take into account when positioning other elements relative to it. Also, FrameworkElements allow for styling, and they possess their own DataContext property, which allows for binding scenarios that would otherwise not be possible. If AccessText were not a FrameworkElement, it would be unnecessarily limiting and prevent reasonable (though perhaps rare) use cases WPF developers may have.

Edit

Here's an example of a fancy power button that demonstrates the usefullness of AccessText being a 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>

This results in (after pressing Alt):

enter image description here

After clicking the button, or pressing Alt+S, the view model would respond to the command by changing the Text and Fill, resulting in this:

enter image description here

Clicking or using the access key again would return to the first state.

like image 160
devuxer Avatar answered Sep 17 '22 11:09

devuxer