How to select ListBoxItem when a button is clicked in a Template?

I have the following data template applied to a ListBox:

<DataTemplate x:Key="MyTemplate" DataType="{x:Type DAL:Person}">
    <StackPanel Orientation="Horizontal">
        <Button Content="X" Command="{x:Static cmd:MyCommands.Remove}"/>
        <TextBlock Text="{Binding Person.FullName}" />
    </StackPanel>
</DataTemplate>

When I click on the button, the command starts, but ListBoxItem is not selected. How to make it choose so that I can get the selected item in my "executable" method?

thank

+5
source share
3 answers

The best way, since you are not very interested in choosing an element (because it will be deleted quickly anyway), would pass the element directly to the command as the CommandParameter parameter.

Alternatively, you can do a workaround using code or triggers, but I don't think it will. For instance:

ButtonBase.Click ,

<ListBox ButtonBase.Click="lb_Click"
...

, :

private void lb_Click(object sender, RoutedEventArgs e)
{
    object clicked = (e.OriginalSource as FrameworkElement).DataContext;
    var lbi = lb.ItemContainerGenerator.ContainerFromItem(clicked) as ListBoxItem;
    lbi.IsSelected = true;
}

, datacontext , ListBoxItem ListBox ItemContainerGenerator IsSelected true. . , ButtonBase .

, ( ), Behavior:

public class SelectItemOnButtonClick : Behavior<ListBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(handler), true);
    }
    protected override void OnDetaching()
    {
        this.AssociatedObject.RemoveHandler(ButtonBase.ClickEvent, new RoutedEventHandler(handler));
        base.OnDetaching();
    }
    private void handler(object s, RoutedEventArgs e)
    {
        object clicked = (e.OriginalSource as FrameworkElement).DataContext;
        var lbi = AssociatedObject.ItemContainerGenerator.ContainerFromItem(clicked) as ListBoxItem;
        lbi.IsSelected = true;
    }
}

:

<ListBox xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" ...>
    <i:Interaction.Behaviors>
        <local:SelectItemOnButtonClick />
    </i:Interaction.Behaviors>
</ListBox>

, , , , , , , .

, Handled true , (MouseDown/Click), ListBoxItem. MouseDown ListBox , ListBoxItem, ... , , , , , FrameworkContentElements ( MouseDown), , , , datatemplate, ListBoxItem , , .

-, , , ( ... err thingies). , , , reaaaly , , . , - , .

+8

RemoveCommand Command. ; , , .

+1

Alex, thanks for the answer. Your decision with Behavior is great. The first solution is not so good, because it will work only if you click on a specific button. Here is another solution that will work when you click on the arbitrary form of the ListBoxItem form:

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem" 
           BasedOn="{StaticResource {x:Type ListBoxItem}}">
        <Style.Triggers>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                <Setter Property="IsSelected" Value="True"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</ListBox.ItemContainerStyle>

This is the XAML approach. I also set the BasedOn property so as not to override the current ListBoxItem style.

0
source

All Articles