Home > Back-end >  How to add a button for each item in a ListBox
How to add a button for each item in a ListBox

Time:12-14

I am trying to add a button for each item in a ListBox. It is like this: enter image description here

Style template before adding a button:

<Style TargetType="ListBox" x:Key="ListBoxStyle">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <ItemsPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
</Style>
<Style TargetType="ListBoxItem" x:Key="ListBoxItemStyle">
    <Setter Property="Canvas.Left" Value="{Binding Rectangle.X}"/>
    <Setter Property="Canvas.Top" Value="{Binding Rectangle.Y}"/>
    <Setter Property="Width" Value="{Binding Rectangle.Width}"/>
    <Setter Property="Height" Value="{Binding Rectangle.Height}"/>
    <Setter Property="BorderBrush" Value="{Binding Hexadecimal}"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="Content" Value=""/>
</Style>

This is how I use the style:

<ListBox
    ItemsSource="{Binding LabelShapes}"
    Width="{Binding ActualWidth, ElementName=Img}"
    Height="{Binding ActualHeight, ElementName=Img}"
    VerticalAlignment="Top"
    HorizontalAlignment="Left"
    SelectionMode="Extended"
    Style="{StaticResource ListBoxStyle}"
    ItemContainerStyle="{StaticResource ListBoxItemStyle}"/>

Add a button by using canvas:

<Style TargetType="ListBoxItem" x:Key="ListBoxItemStyle">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Canvas>
                    <Border
                    Canvas.Left="{Binding Rectangle.Left}"
                    Canvas.Top="{Binding Rectangle.Top}"
                    Width="{Binding Rectangle.Width}"
                    Height="{Binding Rectangle.Height}"
                    BorderBrush="{Binding Hexadecimal}"
                    BorderThickness="2"/>

                    <Grid Height="20" Canvas.Left="{Binding Rectangle.Left}" Canvas.Top="{Binding Rectangle.Bottom}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="50"/>
                        </Grid.ColumnDefinitions>
                        <Button Grid.Column="2" Width="50" Height="30" />
                    </Grid>
                </Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

My question is that when I add a button by using canvas, the ListBoxItem can not be selected. What is the right way to style ListBoxItem and to make the ListBoxItem can be selected? Any help will be greatly appreciated.

UPDATE

I add some visual states:

<Style TargetType="ListBoxItem" x:Key="ListBoxItemStyle">
    <Setter Property="Canvas.Left" Value="{Binding Rectangle.X}"/>
    <Setter Property="Canvas.Top" Value="{Binding Rectangle.Y}"/>
    <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border x:Name="MyBorder"
                    Width="{Binding Rectangle.Width}"
                    Height="{Binding Rectangle.Height}"
                    BorderBrush="{Binding Hexadecimal}"
                    BorderThickness="2">
                    <Border.Background>
                        <SolidColorBrush Color="Transparent" />
                    </Border.Background>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard> 
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="MyBorder" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="{StaticResource SelectedBackgroundColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="SelectedUnfocused">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="MyBorder" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="{StaticResource SelectedUnfocusedColor}" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Grid Height="20" Canvas.Left="{Binding Rectangle.Left}" Canvas.Top="{Binding Rectangle.Bottom}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="50"/>
                        </Grid.ColumnDefinitions>
                        <Button Width="50" Height="30" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The items can now be selected, but I can't figure out how to put a button at the bottom of the border?

enter image description here

CodePudding user response:

I found a simple way to get what I need. Replace the ControlTemplate of the ListBoxItem by the following, and use ControlTemplate.Triggers Property to handle the style of selected item.

<ControlTemplate TargetType="ListBoxItem">
    <Grid>
        <Rectangle
            x:Name="ShapeBorder" 
            HorizontalAlignment="Left"
            Width="{Binding Rectangle.Width}"
            Height="{Binding Rectangle.Height}"
            Stroke="{Binding Hexadecimal}"
            StrokeThickness="1"/>
    
        <Grid Height="20" Margin="0 0 0 -20" VerticalAlignment="Bottom">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="2" Width="50" Height="20" />
        </Grid>
    </Grid>

    <ControlTemplate.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter TargetName="ShapeBorder" Property="StrokeThickness" Value="2"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
  • Related