MaterialDesignInXAML / MaterialDesignInXamlToolkit

Google's Material Design in XAML & WPF, for C# & VB.Net.
http://materialdesigninxaml.net
MIT License
14.91k stars 3.4k forks source link

Expander content is not focusable anymore #2791

Open chrizzz86 opened 2 years ago

chrizzz86 commented 2 years ago

Bug explanation

Due to setting Focusable="False" for ContentPresenter inside Grid "ContentPanel" it's not possible anymore to set focus on content controls

Version

4.6.0.0 prerelease

ElieTaillard commented 2 years ago

Indeed, it's problematic...

greuelpirat commented 1 year ago

I just tried the following

<Expander HorizontalAlignment="Stretch" Header="Expander Example 1a">
  <Button Content="Hello"></Button>
</Expander>

When I set Focusable=True this adds a tab stop to the content presenter:

  1. ToggleButton (in Header)
  2. ContentPresenter 🆕
  3. Button "Hello"

(Unfortunately KeyboardNavigation.IsTabStop="False" does not work here for me)

Why do you need to focus the ContentPresenter? The button/content can still be focused.

chrizzz86 commented 1 year ago

In my case I had a TextBox inside the Expander control. The focus was set automatically by DataTrigger when control expands. This was working properly in previous versions.

From version 4.6 there is a new setting Focusable="False" for the ContentPresenter Name="PART_Content" inside the ControlTemplate. I guess based on this change it is not working anymore.

Keboo commented 1 year ago

@chrizzz86 can you provide additional feedback on your setup. I wrote a UI test to try and reproduce the problem but I am unable to.

chrizzz86 commented 1 year ago

Hi, yes, for sure...

<Expander ExpandDirection="Left"
                  DataContext="{Binding SearchViewModel}"
                  IsExpanded="{Binding IsExpanded, Mode=TwoWay}"
                  Style="{StaticResource MaterialDesignExpander}"
                  VerticalAlignment="Stretch"
                  HorizontalAlignment="Right">

            <Expander.Header>
                <TextBlock
                    Text="{x:Static loc:Controls.Search}"
                    RenderTransformOrigin=".5,.5">
                    <TextBlock.LayoutTransform>
                        <RotateTransform Angle="90" />
                    </TextBlock.LayoutTransform>
                </TextBlock>
            </Expander.Header>

            <GroupBox Margin="5"
                      Style="{StaticResource MaterialDesignCardGroupBox}">

                <GroupBox.Header>
                    <StackPanel Orientation="Horizontal">
                        <ContentPresenter Content="{StaticResource EventSearchWhite}" />
                        <TextBlock Text="{x:Static loc:Controls.SearchTooltip}"
                               Margin="3,0,0,0"
                               Foreground="White" />
                    </StackPanel>
                </GroupBox.Header>

                <DockPanel>

                    <TextBox DockPanel.Dock="Top"
                             GotFocus="TextBoxGotFocus"
                             Margin="5"
                             materialDesign:TextFieldAssist.HasClearButton="True"
                             materialDesign:HintAssist.Hint="{x:Static loc:Controls.FilterHint}"
                             VerticalAlignment="Center"
                             Text="{Binding Filter, UpdateSourceTrigger=PropertyChanged, Delay=200}">

                        <TextBox.InputBindings>
                            <KeyBinding Command="{Binding SelectCurrentItemAndCloseCommand}"
                                        Key="Return" />
                        </TextBox.InputBindings>

                        <TextBox.Style>
                            <Style TargetType="TextBox"
                                BasedOn="{StaticResource MaterialDesignOutlinedTextBox }">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsExpanded}" Value="True">
                                        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBox.Style>

                    </TextBox>

                    ...AND SOMETHING MORE...

                </DockPanel>

            </GroupBox>

        </Expander>
greuelpirat commented 1 year ago

Great, I reproduced your issue (needed some changes for DataContext etc...)

But even if I set Focusable="True" on the ContentPresenter PART_Content the focus when expanding does not work:

expander-focus

To be honest: I expected this, but I can not explain why this worked before. I will try make some additional tests. But I would recommend to keep Focusable=False due to the keyboard navigation behaviour.

greuelpirat commented 1 year ago

the focus works when changes from 0c8779003b9a497efd3b73a7b013742e42f015b3 are reverted:

expander-focused

The focus does not work anymore because the Expander-content is collapsed when FocusManager is called. I think #2579 is still a good change.

To make it work again, the focus must be delayed. The fasted way I found is to use an event handler to queue the focus with priority Loaded:

<Expander Expanded="OnExpanded" ...>
  <TextBox x:Name="TextBoxToFocus" ...>
</Expander>
private void OnExpanded(object sender, RoutedEventArgs e)
{
  Dispatcher.InvokeAsync(TextBoxToFocus.Focus, DispatcherPriority.Loaded);
}
github-actions[bot] commented 1 year ago

This issue is marked stale because it has been open 30 days with no activity. Remove stale label or update the issue, otherwise it will be closed in 14 days.