1

I create buttons as ListBox items. Using keyboard shortcut, the selected item/button will be changed to the button where the first character is the same with the pressed key. The problem is the focused item (dashed rectangle) will not be synchronized with selected item. This problem doesn't exist if we use keyboard arrow. The shorted code is:

        <ListBox x:Name="ListBoxRef" 
             ScrollViewer.HorizontalScrollBarVisibility="Disabled"
             DataContext="{Binding Path=ListViewSource}" IsSynchronizedWithCurrentItem="True"
             ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Tag="{Binding}" IsTabStop="False"
                        Command="{Binding ElementName=UserControlTypeSelectionView, Path=DataContext.SelectCommand}"
                        CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
                    <Button.Template>
                        <ControlTemplate>
                            <TextBlock Text="{Binding Path=Name}" />
                        </ControlTemplate>
                    </Button.Template>
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ListBox>

In How do you programmatically set focus to the SelectedItem in a WPF ListBox that already has focus?, the solution is using the Focus method and in C# side.

Is it possible using only XAML in MVVM?

Community
  • 1
  • 1
Yohanes Nurcahyo
  • 601
  • 8
  • 19
  • you may perhaps sync them using an attached behavior. as a workaround with pure xaml you can hide the dashed focused rectangle thus eliminating the issue. – pushpraj Aug 11 '14 at 08:49
  • @pushpraj Yes, that is my current solution. But I am not sure this is the best solution. I expect solution only in XAML without addition extension if it is possible. – Yohanes Nurcahyo Aug 11 '14 at 08:53
  • try adding a null or empty focus template to the listbox item. – pushpraj Aug 11 '14 at 08:55

3 Answers3

7

I found the answer from my colleague. By Triggering FocusManager.FocusedElement with current selected item setter (IsSelected property) the problem is solved.

        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <!-- Edited: add pushpraj code to hide the dashed rectangle on focused item -->
                <Setter Property="FocusVisualStyle" Value="{x:Null}" /> 
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
Yohanes Nurcahyo
  • 601
  • 8
  • 19
  • I add your code for hiding the dashed rectangle focus indicator. I didn't check in my code because my colleague will put it on the default ListBox style. – Yohanes Nurcahyo Aug 11 '14 at 10:09
1

if you are not interested in the focus (dashed) rectangle and only interested in pure xaml solution then you may perhaps hide it

here is a sample

<ListBox>
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="FocusVisualStyle"
                    Value="{x:Null}" />
        </Style>
    </ListBox.Resources>
    <ListBoxItem>item 1</ListBoxItem>
    <ListBoxItem>item 2</ListBoxItem>
    <ListBoxItem>item 3</ListBoxItem>
</ListBox>

the interesting area in the sample is the Style for ListBoxItem which sets a null value for FocusVisualStyle which is usually the dashed rectangle.

this is not equivalent to syncing the focused element with the selected item but it is hiding the focus layer so the dashed rectangle do not appear.

pushpraj
  • 13,458
  • 3
  • 33
  • 50
  • That is exactly also what I need to hide the dash. +1 For you. But this is not the solution for my question. For example if we have button "AAA", "BBB", "CCC", "DDD" and "EEE". If the selected item button is on "CCC" but the focused item/button is on "AAA" and if we pressed right arrow, we expect the next selected button is "DDD" because the focused button is unknown and the marked is "CCC". But the result is "BBB". – Yohanes Nurcahyo Aug 11 '14 at 09:25
  • That is something what I am afraid of. btw is is possible for you to provide a working sample of your code, may I try to find a solution for you. – pushpraj Aug 11 '14 at 09:27
  • thank you for your effort to answer. But I am afraid I cannot share my company's code. By the way I got the answer from my colleague. But I will appreciate if you have the better solution. – Yohanes Nurcahyo Aug 11 '14 at 09:42
  • You may combine both of them in a single style and that's your full solution, which hides the dashed rectangle and solves the mentioned concern. – pushpraj Aug 11 '14 at 09:50
  • @YohanesNurcahyo can you please share your solution here? – Mohini Mhetre Feb 26 '16 at 08:52
0

@YohanesNurcahyo, great answer only when ListBox SelectionMode is set to Single. Here is my update:

<ListBox.ItemContainerStyle>
  <Style TargetType="{x:Type ListBoxItem}">
    <!-- Edited: add pushpraj code to hide the dashed rectangle on focused item -->
    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
    <Style.Triggers>
      <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
          <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True" />
          <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=SelectionMode}" Value="Single" />
        </MultiDataTrigger.Conditions>
        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}" />
      </MultiDataTrigger>
    </Style.Triggers>
  </Style>
</ListBox.ItemContainerStyle>

else, it would break multiple selection if any (provided that the ListBox SelectedItems property read-only restriction has been overridden).