Page 1 of 1

drop down default focus problem

Posted: 02 Apr 2021, 19:12
by sgonchar
Hello,

We're having issues with default focus in drop downs with keyboard and controller:
Image
- When entering screen / panel I press A or Return to open the drop down.
- Drop down shows, but Inspector doesn't show PopupLayer
- Note no highlight. Nav with keyboard or controller doesn't work.
- Mouse over highlight works
- Clicking with the Mouse selects a value
- Now A/Enter on keyboard opens the drop down and highlight is visible, PopupLayer is in Inspector / things work as expected.

Question: Is this a problem with our style? Or something else is going on?

Our dropdown definition:
    <ComboBox x:Name="Colors" noesis:Text.Placeholder="Pick a color" Margin="-200,0,0,0" Width="150" HorizontalAlignment="Left" >
      <ComboBox.Style>
        <Style TargetType="ComboBox" BasedOn="{StaticResource DropdownComboBoxStyle}">
        </Style>
      </ComboBox.Style>
      <ComboBoxItem Content="Red"/>
      <ComboBoxItem Content="Green"/>
      <ComboBoxItem Content="Blue"/>
    </ComboBox>
Note that adding SelectedIndex="0" to <ComboBox .. > makes things work perfectly, however, we're need to make the initial value blank (force user selection vs mash "enter" to skip through stuff) and selectedIndex seems to overwite Placeholder text.
<ComboBox x:Name="Colors" noesis:Text.Placeholder="Pick a color" Margin="-200,0,0,0" Width="150" HorizontalAlignment="Left" SelectedIndex="0" > 
...
... 
Our Style definition:
<ResourceDictionary
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions"
  xmlns:System="clr-namespace:System;assembly=mscorlib"
  x:Name="ComboBoxes"
>
  <ControlTemplate x:Key="DropdownToggleButton" TargetType="{x:Type ToggleButton}">
    <Rectangle x:Name="Rectangle" Fill="{TemplateBinding Background}" Opacity="0.15" RadiusX="4" RadiusY="4" />
  </ControlTemplate>
  <Style x:Key="DropdownBoxItem" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type ComboBoxItem}">
          <Border
            x:Name="Border"
            Padding="20"
            SnapsToDevicePixels="true"
            Background="{DynamicResource ColorBrush.light.ui-fill.resting}"
          >
            <ContentPresenter />
          </Border>
          <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
              <Setter
                Property="Background"
                Value="{DynamicResource ColorBrush.light.ui-fill.highlight}"
                TargetName="Border"
              />
            </Trigger>
            <Trigger Property="IsFocused" Value="True">
              <Setter
                Property="Background"
                Value="{DynamicResource ColorBrush.light.ui-fill.highlight}"
                TargetName="Border"
              />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
  <DataTemplate x:Key="StringItemTemplate">
    <TextBlock Text="{Binding DropdownText}" />
  </DataTemplate>
  <DataTemplate x:Key="MonthItemTemplate">
    <StackPanel Orientation="Horizontal">
      <TextBlock Text="{Binding DropdownText}" />
      <TextBlock Text=" - " />
      <TextBlock Text="{Binding DropdownSubtext}" />
    </StackPanel>
  </DataTemplate>
  <ControlTemplate x:Key="DropdownComboBox" TargetType="{x:Type ComboBox}">
    <Border x:Name="border" BorderBrush="#5E0BC4E2" Margin="-9" BorderThickness="5" CornerRadius="12" Padding="4">
      <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
          <VisualStateGroup.Transitions>
            <VisualTransition GeneratedDuration="0:0:0.25">
              <VisualTransition.GeneratedEasingFunction>
                <QuarticEase EasingMode="EaseOut" />
              </VisualTransition.GeneratedEasingFunction>
            </VisualTransition>
          </VisualStateGroup.Transitions>
          <VisualState x:Name="Normal">
            <Storyboard>
              <ColorAnimationUsingKeyFrames
                Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                Storyboard.TargetName="border"
              >
                <EasingColorKeyFrame KeyTime="0" Value="#000BC4E2" />
              </ColorAnimationUsingKeyFrames>
            </Storyboard>
          </VisualState>
          <VisualState x:Name="Pressed" />
          <VisualState x:Name="Disabled" />
        </VisualStateGroup>
        <VisualStateGroup x:Name="FocusStates">
          <VisualStateGroup.Transitions>
            <VisualTransition GeneratedDuration="0:0:0.25" To="Focused">
              <VisualTransition.GeneratedEasingFunction>
                <QuadraticEase EasingMode="EaseOut" />
              </VisualTransition.GeneratedEasingFunction>
            </VisualTransition>
            <VisualTransition From="Focused" GeneratedDuration="0:0:0.25">
              <VisualTransition.GeneratedEasingFunction>
                <QuadraticEase EasingMode="EaseOut" />
              </VisualTransition.GeneratedEasingFunction>
            </VisualTransition>
          </VisualStateGroup.Transitions>
          <VisualState x:Name="Unfocused">
            <Storyboard>
              <ColorAnimationUsingKeyFrames
                Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
                Storyboard.TargetName="border"
              >
                <EasingColorKeyFrame KeyTime="0" Value="#000BC4E2" />
              </ColorAnimationUsingKeyFrames>
            </Storyboard>
          </VisualState>
          <VisualState x:Name="Focused" />
        </VisualStateGroup>
      </VisualStateManager.VisualStateGroups>
      <Grid>
        <TextBlock
          x:Name="Placeholder"
          Text="{Binding (noesis:Text.Placeholder), RelativeSource={RelativeSource TemplatedParent}}"
          Margin="23"
          VerticalAlignment="Top"
          HorizontalAlignment="Left"
          Focusable="False"
          Padding="0,0,0,20"
        >
          <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
              <Setter Property="FontFamily" Value="Mark Pro" />
              <Setter Property="FontWeight" Value="Bold" />
              <Setter Property="FontSize" Value="18" />
              <Setter Property="Foreground" Value="{DynamicResource ColorBrush.dark.text-secondary}" />
            </Style>
          </TextBlock.Style>
        </TextBlock>
        <ToggleButton
          Template="{StaticResource DropdownToggleButton}"
          ClickMode="Press"
          Foreground="{TemplateBinding Foreground}"
          Background="{TemplateBinding Background}"
          IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
          Focusable="False"
        >
          <i:Interaction.Triggers>
            <ei:KeyTrigger Key="Return" FiredOn="KeyDown">
              <i:Interaction.Behaviors>
                <ei:ConditionBehavior>
                  <ei:ConditionalExpression>
                    <ei:ComparisonCondition LeftOperand="{Binding IsFocused, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Operator="Equal" RightOperand="True" />
                  </ei:ConditionalExpression>
                </ei:ConditionBehavior>
              </i:Interaction.Behaviors>
              <noesis:SetFocusAction />
              <ei:ChangePropertyAction PropertyName="IsChecked" Value="True" />
            </ei:KeyTrigger>
            <noesis:GamepadTrigger FiredOn="ButtonDown" Button="Accept">
              <i:Interaction.Behaviors>
                <ei:ConditionBehavior>
                  <ei:ConditionalExpression>
                    <ei:ComparisonCondition LeftOperand="{Binding IsFocused, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Operator="Equal" RightOperand="True" />
                  </ei:ConditionalExpression>
                </ei:ConditionBehavior>
              </i:Interaction.Behaviors>
              <noesis:SetFocusAction />
              <ei:ChangePropertyAction PropertyName="IsChecked" Value="True" />
            </noesis:GamepadTrigger>
          </i:Interaction.Triggers>
        </ToggleButton>
        
        <ContentPresenter
          x:Name="ContentSite"
          IsHitTestVisible="False"
          Margin="23,43,0,0"
          VerticalAlignment="Center"
          HorizontalAlignment="Left"
          Content="{TemplateBinding SelectionBoxItem}"
          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
        >
          <ContentPresenter.Style>
            <Style TargetType="ContentPresenter">
              <Setter
                Property="ContentTemplate"
                Value="{Binding SelectionBoxItemTemplate, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}"
              />
              <Style.Triggers>
                <DataTrigger
                  Binding="{Binding Path=ItemTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                  Value="{StaticResource MonthItemTemplate}"
                >
                  <Setter Property="ContentTemplate" Value="{StaticResource StringItemTemplate}" />
                </DataTrigger>
              </Style.Triggers>
            </Style>
          </ContentPresenter.Style>
        </ContentPresenter>
        <TextBox x:Name="PART_EditableTextBox" Visibility="Hidden" />
        <Popup x:Name="PART_Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}">
          <Grid
            x:Name="DropDown"
            SnapsToDevicePixels="True"
            MinWidth="{TemplateBinding ActualWidth}"
            MaxHeight="{TemplateBinding MaxDropDownHeight}"
          >
            <Border x:Name="DropDownBorder" BorderThickness="1" CornerRadius="15">
              <Border.BorderBrush>
                <SolidColorBrush Color="{DynamicResource Color.light.ui-fill.resting}" />
              </Border.BorderBrush>
              <Border.Background>
                <SolidColorBrush Color="{DynamicResource Color.light.ui-fill.resting}" />
              </Border.Background>
            </Border>
            <ScrollViewer Margin="0,6,0,6" SnapsToDevicePixels="True" Padding="0,6">
              <ScrollViewer.Resources>
                <Style TargetType="{x:Type ScrollViewer}">
                  <Setter Property="Template">
                    <Setter.Value>
                      <ControlTemplate TargetType="{x:Type ScrollViewer}">
                        <ScrollContentPresenter
                          CanContentScroll="{TemplateBinding CanContentScroll}"
                          Margin="{TemplateBinding Padding}"
                        />
                      </ControlTemplate>
                    </Setter.Value>
                  </Setter>
                </Style>
              </ScrollViewer.Resources>
              <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
            </ScrollViewer>
          </Grid>
        </Popup>
      </Grid>
    </Border>
  </ControlTemplate>
  <Style x:Key="DropdownComboBoxStyle" TargetType="{x:Type ComboBox}">
    <Setter Property="FontFamily" Value="Mark Pro" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="FontSize" Value="22" />
    <Setter Property="Foreground" Value="{DynamicResource ColorBrush.dark.text-primary}" />
    <Setter Property="Background" Value="{DynamicResource ColorBrush.dark.ui-fill.resting}" />
    <Setter Property="Template" Value="{StaticResource DropdownComboBox}" />
    <Setter Property="ItemTemplate" Value="{StaticResource StringItemTemplate}" />
    <Setter Property="ItemContainerStyle" Value="{StaticResource DropdownBoxItem}" />
    <Setter Property="MaxDropDownHeight" Value="350" />
    <Setter Property="noesis:StyleInteraction.Triggers">
      <Setter.Value>
        <noesis:StyleTriggerCollection>
          <i:EventTrigger EventName="SelectionChanged">
            <noesis:SetFocusAction />
          </i:EventTrigger>
        </noesis:StyleTriggerCollection>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Re: drop down default focus problem

Posted: 05 Apr 2021, 11:49
by jsantos
Sorry for the delay in this answer. Today is a public holiday for us. We started to investigate your issue and will tell you something very soon.

Re: drop down default focus problem

Posted: 05 Apr 2021, 12:43
by sfernandez
I did some tests and I can confirm this is a bug in Noesis code, it doesn't behave as expected compared to WPF when no initial selection was made in the ComboBox.
Could you please report it in our bugtracker and we will fix it for the next release?

Regarding the Inspector, I guess you are launching it from a different computer, otherwise drop down popup will automatically close as soon as the game window is deactivated and you won't be able to refresh visual tree in the Inspector to see the popup layer. I verified that popup shows fine in Inspector even if ComboBox has nothing selected.

Re: drop down default focus problem

Posted: 05 Apr 2021, 16:32
by sgonchar
No worries, it's a holiday in many places.

Thank you. reported in bugtracker #1958

Re: drop down default focus problem

Posted: 08 Apr 2021, 12:24
by jsantos
We solved this. The fix will be available in the next release (3.0.12). Thanks for your feedback.