1

A few questions regarding ListBox here (3 actually)

alt text

1. ListBoxItem/Rectangle Margins

From the image, I think the margins are uneven, the left seems like it have more margin. And this is when my margins is already set to

<ListBox.ItemTemplate>
    <DataTemplate>
        <Rectangle Width="20" Height="20" Margin="1,2,2,2">
            <Rectangle.Fill>
                <SolidColorBrush Color="{Binding}" />
            </Rectangle.Fill>
        </Rectangle>
    </DataTemplate>
</ListBox.ItemTemplate>

2. How can I change the Selected Item Look?

I don't want that blue background, can I just have a border?

I tried the example from Change WPF DataTemplate for ListBox item if selected

with this code

<ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Rectangle Width="20" Height="20" Margin="1,2,3,2">
                        <Rectangle.Fill>
                            <SolidColorBrush Color="{Binding}" />
                        </Rectangle.Fill>
                    </Rectangle>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Border BorderBrush="DarkGray" BorderThickness="1">
                                <Rectangle Width="20" Height="20" Margin="1,2,3,2">
                                    <Rectangle.Fill>
                                        <SolidColorBrush Color="{Binding}" />
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Border>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</ListBox.ItemContainerStyle>

and got something like

alt text

3. Binding for Selected Item

I am trying to bind the selected color to a property of the view model. If the color in the view model does not exists in the list of colors provided, no color should be selected. Think of this as an alternative way to select color, I have selection of colors via RGB/HSB sliders. I tried

<ListBox ItemsSource="{Binding ThemeColors}" SelectedValue="{Binding Color}" SelectionChanged="ListBox_SelectionChanged" ...

then in C#

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var listBox = (ListBox)sender;
    if (listBox.SelectedValue != null) 
        Color = (Color)listBox.SelectedValue;
}

But after that, when I try to select colors with the sliders, I get some weird jerking and sometimes the color always snap back to the color selected from the list box. But sometimes it works fine, I am quite confused.

Community
  • 1
  • 1
Jiew Meng
  • 84,767
  • 185
  • 495
  • 805

1 Answers1

2

1.ListBoxItem comes with a default Padding of "2,0,0,0", that's why the Margin seems of. This can be changed in the ItemContainerStyle of the ListBox

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Padding" Value="0,0,0,0"/>
    </Style>
</ListBox.ItemContainerStyle>

(Although I seem to get the best result with a Padding of 1,0,0,0. Can't explain that..)

2.To remove the Background and only display the Border I think you'll have to retemplate the ListBoxItem and modify the Triggers to use BorderBrush instead of Background for the Border.

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="Padding" Value="0,0,0,0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Padding="{TemplateBinding Padding}">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="BorderBrush" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="Selector.IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="BorderBrush" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ListBox.ItemContainerStyle>

For 3. I'm not sure I understand what you want to do

Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266