style of selected item in lisbox - wpf

I have a list box which is bound to a list of strings.
<ListBox Grid.Row="1"
Height="130"
Background="Black" BorderThickness="0"
ItemsSource="{Binding Images}"
ItemTemplate="{StaticResource PanoItemTemplate}"
SelectedItem="{Binding SelectedImage}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
Height="110"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
and in VM I have:
public ObservableCollection<string> Images
{
get { return _images; }
}
public string SelectedImage
{
get { return _selectedImage; }
set
{
_selectedImage = value;
OnPropertyChanged("SelectedImage");
}
}
When I populate Image list and select one of them in listbox by clicking on it, I can get it in SelectedImage and the system works well.
When I click on an item on list box, it shows as selected I ListBox (Blue colour on white background).
If I set the SelectedImage in code to an item which is in image list, that item is selected on list, but the colour is different (it is white on white background).
How can I change the style of selectedImage when I select them via code to be the same as when user select them?

The ListBox will only highlight blue when it has user focus, otherwise it uses a different brush
When the ListBox is focused it used SystemColors.HighlightTextBrushKey, and when unfocused it uses SystemColors.InactiveSelectionHighlightBrushKey
So you could set the SystemColors.InactiveSelectionHighlightBrushKey to the SystemColors.HighlightColor, this will keep it blue in and out of focus.
Example:
<ListBox >
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="{x:Static SystemColors.HighlightColor}"/>
</ListBox.Resources>
</ListBox>
Edit:
For .NET4.0 and below you may have to use SystemColors.ControlBrushKey instead of SystemColors.InactiveSelectionHighlightBrushKey
<ListBox >
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{x:Static SystemColors.HighlightColor}"/>
</ListBox.Resources>
</ListBox>

Related

Adjust ListBox items width based on its content

<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" >
</UniformGrid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem HorizontalContentAlignment="Stretch">listbox item 1</ListBoxItem>
<ListBoxItem>listbox item 2</ListBoxItem>
<ListBoxItem>listbox item 3</ListBoxItem>
<ListBoxItem>listbox item 4</ListBoxItem>
<ListBoxItem>listbox item 5</ListBoxItem>
</ListBox>
I have added ListBoxItems as above and used UniformGrid to display it. but I can't achieve content based width for each of the list box item. I have tried HorizontalContentAlignment as Stretch and Auto width properties. Nothing happened.
You have to use HorizontalAlignment instead of HorizontalContentAlignment.
<ListBoxItem HorizontalAlignment="Left">listbox item 1</ListBoxItem>
If you want to set the alignment for all items, consider creating an item container style.
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</ListBox.ItemContainerStyle>
<!-- ...your code. -->
</ListBox>
Please note that the default value for HorizontalAlignment is already Stretch, so you will not see a difference there. Furthermore, there is no Auto. The possible values are Left, Right, Center and Stretch. All values except for Stretch will size to the content.

WPF Style Selected Items of ListBox Using an ItemsPanelTemplate

How can I style the selected items in this listbox?
<ListBox x:Name="AssetTypeListBox" SelectionMode="Multiple">
<ListBox.ItemsPanel >
<ItemsPanelTemplate >
<UniformGrid Columns="6"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
I have tried
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#F15025"/>
and
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="#F15025"/>
But they don't seem to affect the selected items as I would expect. Thanks.
If you just want to change the colour of the selection, then the easiest way is to set the solidcolorbrush as a resource on your Listbox:
<ListBox x:Name="AssetTypeListBox" SelectionMode="Multiple">
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#F15025"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="#F15025"/>
</ListBox.Resources>
<ListBox.ItemsPanel >
<ItemsPanelTemplate >
<UniformGrid Columns="6"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
If you're wanting to customise the style of the selection of an item in the listbox, such as changing the selection colour or completely restyling the look of a selected item, you need to look at the ItemContainerStyle property.
The ItemsPanelTemplate doesn't affect this - it simply sets the ItemsControl type that should layout and present the items - such as a StackPanel or UniformGrid.
The basic hierarchy (with a pinch of salt) of a ListBox is:
ListBox
ItemsPanelTemplate (StackPanel by default)
ItemsContainerStyle (Selection highlighting is here)
ItemTemplate (You define the content of your list item here)
The differences between ItemTemplates and ItemsContainerStyle are covered here:
What's the difference between ItemTemplate and ItemContainerStyle in a WPF ListBox?

WPF Listbox containing Expander controls

I've been playing around with wpf for a few months with mixed success but this one has me stumped. I have a ListBox containing Expanders, something like this:
<ListBox>
<Expander Header="Options">
<StackPanel>
<CheckBox Content="Option 1" />
<CheckBox Content="Option 2" />
<CheckBox Content="Option 3" />
</StackPanel>
</Expander>
<Expander Header="More Options">
<StackPanel>
<CheckBox Content="Option 1" />
<CheckBox Content="Option 2" />
<CheckBox Content="Option 3" />
</StackPanel>
</Expander>
</ListBox>
I'm trying to figure out how to:
Prevent the content portion of the Expander from changing colour when it is selected in the ListBox. I want only the Expander's header to have a blue background, not the CheckBoxes
Make an Expander the selected item in the ListView when its header is clicked. At the moment you have to click outside of the Expander's header's text to have it become selected in the list view
The solution to your first question is simple. Just add this into the ListBox.Resources:
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
</ListBox.Resources>
You are free to change the colours to any that you prefer.
The solution to your second question is far from simple. I should like to say that declaring controls inside a ListBox is far from optimal. A much better solution is to create a data type class, bind a collection of these instances to the ListBox.ItemsSource property and then to create DataTemplates to define what each item should look like... that is where you should declare your Expander controls.
As at StackOverflow, we prefer one question to be asked per post, please try what I have just suggested, searching for the relevant terms online if necessary, and then come back with a new question, showing us your new code.

Is there something like a WPF listview without the selection?

The application I'm developing has a kind of accordion made of expanders but each exapnder acts independently rather than only allowing a single open item at a time. Each expander is related to an item in a collection in the view model.
My currently solution is to use a listbox and then bind the lists itemsource to the collection and have an item template render the expander and the exapnders contents.
The problem is that the listbox treats each expander as an item (obviously) and allows selection and highlighting. Highlighting is a little ugly and could be disabled, but the selection causes me some issues because it causes the list to scroll to show as much of the expanded expander as possible.
Is there a WPF control that is a little like a stackpanel (perhaps) that would allow me to bind the contained controls using item templating but without the selection and highlighting?
<ListBox Grid.Row="0" Grid.Column="0" Width="Auto" SelectionMode="Single" ItemsSource="{Binding Path=MeasurementSources}">
<ListBox.ItemTemplate>
<DataTemplate>
<Expander Header="{Binding Name}" IsEnabled="{Binding Available}">
<ListBox Width="Auto" SelectionMode="Single"
ItemsSource="{Binding Path=Measurements}"
SelectedItem="{Binding Path=SelectedMeasurement}">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text=" "/>
<TextBlock Text="{Binding Created}"/>
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If you want List-like capabilities without selection capabilities, you should use an ItemsControl - incidentally the base class of Selector which in turn is the base class of ListBox
The whole thing then just becomes
<ItemsControl Width="Auto" ItemsSource="{Binding Measurements}"
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text=" "/>
<TextBlock Text="{Binding Created}"/>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Obviously, you cannot bind a selected item in this case.
This is a useful piece of information that I had not realised.
http://msdn.microsoft.com/library/windows/apps/hh780657.aspx
Note ItemsControl is the base class for several common collection
controls, including ListView, GridView, FlipView, ListBox, and
ComboBox controls. These examples use the ListView and GridView
controls, but the info applies generally to ItemsControls.
In other words using the ItemsControl really is the way to solve my issue because using a ListBox and then trying to disable the highlight and the selection functionality really is turning it back into it's own base class.
The best solution is for me:
<Style TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<!-- With focus -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent" />
<!-- Without focus -->
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Transparent" />
<!-- Text foreground -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
Color="Black" />
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
</Style>
and I found it few months ago somwhere on stackoverflow :)

Styling `ListView` menu with round corners

I'm looking to build a menu using a ListView (I'm open to using anything else really that'll achieve the effect I'm looking for. The look I would like to emulate is the following.
Here is what I currently have for my XAML.
<ListView
ItemsSource="{Binding Decisions}"
SelectedItem="{Binding SelectedDecision}"
HorizontalAlignment="Left"
BorderThickness="0"
Width="350"
FontSize="12">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Border
BorderThickness="1"
BorderBrush="#DDD"
CornerRadius="2">
<TextBlock
Text="{Binding Converter={StaticResource DecisionTypeNameConverter}}"
Padding="8"
Background="#EEE" />
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This produces an alright looking menu until I select an item. Once an item is selected it is surrounded by an ugly dark blue. How can I recreate this look (the gradient effect isn't required) in XAML?
Do you need to track the SelectedItem?
If not, I would suggest using an ItemsControl
If so, you need to overwrite the selected item brush color so it doesn't show up. This is a system color, and I usually overwrite it like this:
<ListView.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</ListView>
In order to prevent the blue selection rectangle you would have to set the ItemContainerStyle instead of the ItemTemplate. Consult the MSDN on ListView Styles and Templates to find out about the ListViewItem default style, especially the "Selected" visual state.

Resources