I have a typical MVVM scenario: I have a ListBox that is binded to a List of StepsViewModels. I define a DataTemplate so that StepViewModels are rendered as StepViews. The StepView UserControl have a set of labels and TextBoxs.
What I want to do is to select the ListBoxItem that is wrapping the StepView when a textBox is focused. I've tried to create a style for my TextBoxs with the following trigger:
<Trigger Property="IsFocused" Value="true">
<Setter TargetName="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Property="IsSelected" Value="True"/>
</Trigger>
But I get an error telling me that TextBoxs don't have an IsSelected property. I now that but the Target is a ListBoxItem. How can I make it work?
One way to achieve that is by implementing a custom behavior using an attached property. Basically, the attached property would be applied to the
ListBoxItem
using a style, and would hook up to theirGotFocus
event. That even fires if any descendant of the control gets the focus, so it is suitable for this task. In the event handler,IsSelected
is set totrue
.I wrote up a small example for you:
The Behavior Class:
The Window XAML:
The User Control XAML:
There is a read-only property IsKeyboardFocusWithin that will be set to true if any child is focused. You can use this to set ListBoxItem.IsSelected in a Trigger:
As Jordan0Day correctly pointed out there can be indeed big problems using IsKeyboardFocusWithin solution. In my case a Button in a Toolbar which regards to the ListBox was also not working anymore. The same problem with focus. When clicking the button the ListBoxItem does loose the Focus and the Button updated its CanExecute method, which resulted in disabling the button just a moment before the button click command should be executed.
For me a much better solution was to use a ItemContainerStyle EventSetter as described in this post: ListboxItem selection when the controls inside are used
XAML:
EventHandler in the code behind of the view:
Edit: Someone else already had the same answer on a different question: https://stackoverflow.com/a/7555852/2484737
Continuing on Maexs' answer, using an EventTrigger instead of an EventSetter removes the need for code-behind:
If you create a User Control and then use it as the DataTemplate It seems to work cleaner. Then you don't have to use the dirty Style Triggers that Don't work 100% of the time.