开发者

Listview select "active" item [duplicate]

开发者 https://www.devze.com 2023-04-10 10:54 出处:网络
This question already has answers here: Closed 11 years ago. Possible Duplicate: Select ListBoxItem if TextBox in ItemTemplate gets focus
This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Select ListBoxItem if TextBox in ItemTemplate gets focus

I have a ListView bound to an Obser开发者_运维百科vableCollection (Listview.ItemsSource). The listview presents several textboxes that are bound to properties of the objects in the observable collection.

I would like to have the following functionality: when a user focusses a textbox the corresponding item in the listview should get selected.

I have tried things with ContainerFromElement, ContainerFromItem, etc. but can't get this "simple" functionality to work.

Any ideas...


The trick here is to use the IsKeyboardFocusWithin property on the ItemContainerStyle:

<ListView ItemsSource="{Binding}">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Style.Triggers>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="IsSelected" Value="True" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Path=YourPropertyValue}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

In this example we are simply stating that IsSelected should be set to true whenever a control within that item contains the keyboard focus.

Note: this does not work in the opposite direction; selecting a particular item in the list will not automatically give focus to the contained TextBox

Edit in response to comments

As Joep pointed out, this will mean that losing keyboard focus (which will happen when a control besides the TextBox gains focus) will cause the IsSelected property to be reset to false. You can work around this by replacing the Style setter with an trigger enter action, which prevents the change from being undone when the trigger is no longer valid.

For this to work in the same way as the previous example you will need to explicitly set the SelectionMode for the ListView to Single; otherwise, multiple items can become selected at once.

<ListView ItemsSource="{Binding}" SelectionMode="Single">
   <ListView.ItemContainerStyle>
       <Style TargetType="ListViewItem">
           <Style.Triggers>
               <Trigger Property="IsKeyboardFocusWithin" Value="True">
                   <Trigger.EnterActions>
                       <BeginStoryboard>
                           <Storyboard>
                               <BooleanAnimationUsingKeyFrames
                                  Storyboard.TargetProperty="IsSelected">
                                  <DiscreteBooleanKeyFrame KeyTime="0:0:0" 
                                     Value="True" />
                               </BooleanAnimationUsingKeyFrames>
                           </Storyboard>
                       </BeginStoryboard>
                   </Trigger.EnterActions>
               </Trigger>
           </Style.Triggers>
       </Style>
   </ListView.ItemContainerStyle>
   <!-- ... -->
</ListView>


The MVVM way would add extra properties to the ViewModel representing the properties that are focussed.

E.g., if the ViewModel has a property Name add a property IsNameFocussed, if it has a property Address, add a property IsAddressFocussed.

Then bind the appropriate control in the DataTemplate to the Is...Focussed property to highlight it.

All that is left is setting the Is...Focussed property in the GotFocus and LostFocus events of the textboxes. (I'd rather bind to a Focussed Property but it's not there...)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号