White frame around listbox Item selection on Windows8 - c#

I am getting complaints from Windows8 users about a strange frame around the SelectedItem on ListBoxes
In Windows7 this issue does not exists and so far I have found no way to get rid of this white frame.
As far as I can tell Windows8 listboxes now use ControlBrushKey instead of HighlightBrushKey but setting that to Transparent has no affect.
I have no Windows8 development environment at the moment so all fixes I have tried are pure guess work.
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.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
<Style TargetType="ListBoxItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</ListBox.Resources>
The entire Xaml can be found here: https://github.com/saddam213/MPDisplay/blob/master/GUIFramework/GUI/Controls/GUIList.xaml
Image of the frame: (white box around selection)
If anyone has a clue how to get rid of this it would be great.

In a comment in your original post, you said:
I am not going to rebuild a control just because of a brush that needs to be overridden, I just will not support Windows8 if I need to override a entire ListBox template to remove a selection color, it will be simple once I install Win8 to find the brush using snoop
However, it is not painfully difficult to "rebuild" the ListBoxItem. It may, in fact, be simpler than forcing brushes, as you do not need to worry about overriding every UX change between Windows versions. One particular app I am building right now has the requirement that it run on every OS from XP to 8.1; I achieved a uniform look across all OSes by customizing everything down to the window borders.
Your best bet would be to style every aspect of the ListBoxItem by creating a template, something like the following:
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Obviously, you would need to modify the styles to get the exact behavior you want.

i think this may be helpful for you. use Trigger property for isSelected.
<ListBox Name="lst">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="BorderBrush" Value="Wheat"/>
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

Yes, the last answer really helps.
This is how I get rid of the white frames around ListBoxItem:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Setters>
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="0,0,0,1"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Background" Value="Black"/>
</Style.Setters>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="Black"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

Related

WPF: change listview item background/foreground on selection or mouseover

I have a listview in my WPF program, and I wanted to change the style of the list view items when I hover my mouse over them or when they're selected
This is the code I currently use:
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#1A1A1A"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#1A1A1A"/>
</Trigger>
</Style.Triggers>
</Style>
problem is, that it only changes the border thickness or the font weight
The background and the foreground doesn't change at all
and I can't find any thing that helps online
List view Item on hover:
List view Item when selected:
I've tried using this approach - using my own color values ofc
<Window.Resources>
<Style TargetType="ListViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
</Style.Resources>
</Style>
</Window.Resources>
Then I've also tried disabling focusable - which removes the selection highlight, but also removes the functionality which isn't supposed to happen
This did what I wanted to do
Removed the default hover/selected effect so that I could use setters to make my own effect
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>

XAML partial styling?

I have these controls:
<Border Style="{StaticResource Button}">
<TextBlock>NEW</TextBlock>
</Border>
<Border Style="{StaticResource Button}">
<TextBlock>CLOSE</TextBlock>
</Border>
<Border Style="{StaticResource Button}">
<TextBlock>EXIT</TextBlock>
</Border>
And this style:
<Style x:Key="Button" TargetType="{x:Type Border}">
<Setter Property="Padding" Value="15, 10" />
<Setter Property="Margin" Value="5, 0" />
<Setter Property="MinWidth" Value="150" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand" />
</Trigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
And I want to set each button/border to a specific, different color each, and another color for IsMouseOver.
I tried setting the Background on the control, but then the style can't overwrite the background and I can't do the IsMouseOver change.
I can only think of creating a different style for each one with their colors, but is there anyway to do a partial styling, like how you'd do in CSS?
<div class="button blue">NEW</div>
<div class="button red">CLOSE</div>
<div class="button gray">EXIT</div>
Or any other way to achieve this?
I haven't done any XAML in a while, so I'm a tad rusty. I'm pretty sure you can't do partial styles, but I know you can inherit styles using "BasedOn".
https://msdn.microsoft.com/en-us/library/system.windows.style.basedon(v=vs.110).aspx
This will allow you to do your base button style, and then create a color variant for each color you need based upon the common style features.
<Style x:Key="Button" TargetType="{x:Type Border}">
<Setter Property="Padding" Value="15, 10" />
<Setter Property="Margin" Value="5, 0" />
<Setter Property="MinWidth" Value="150" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand" />
</Trigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
<Style x:Key="ButtonBlue" TargetType="{x:Type Border}" BasedOn="{StaticResource Button}">
<Setter Property="Background" Value="Blue" />
</Style>
Something like that, and then you use "ButtonBlue" instead of "Button" as the static resource you're referencing in the XAML for the control that you want to be blue. You should be able to add triggers as well in the inheriting style. Hopefully I'm remembering my syntax correctly.
Also, you may want to change the style Key to something other than "Button". Could be a bit confusing.

WPF Button Style Template IsEnabled

i based my application on this
example
i need my own button-style (without mouseover animations etc.), so i made this in the app.xaml:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border"
CornerRadius="2" BorderThickness="1"
Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
my button: <Button IsEnabled="true"/>
now if i change the button to <Button IsEnabled="false"/> my app crashes at the start with an error like: "{DependencyProperty.UnsetValue}" is not a valid value for property "BorderBrush".
what am i doing wrong?
It has to do with your static reference.
In particular, XAML parsing is very touchy on order - you have to make sure that a brush with x:Key="DisabledForegroundBrush" is referenced before the parser gets to the line in the above style - even if your style above is in the same file as the DisabledForegroundBrush.
If you don't have a brush yet for the DisabledForegroundBrush, you can either remove the line referencing it in the above code if you don't require it, or, if you want it, you can create one as follows:
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="Red" />
Where you can choose the color as appropriate. Alternatively, you can choose some other kind of brush here: http://msdn.microsoft.com/en-us/library/aa970904(v=vs.110).aspx
If you have a brush you'd like to use already, then if you could provide a little more information as to where the brush is in the code base (eg is it in a resource dictionary?) and where the DisabledForegroundBrush brush is, this might help me pinpoint an actual solution / best way of ensuring the brush is referenced.
Note: an alternative if you can't ensure that DisabledForegroundBrush is parsed first is to change the StaticResource to a DynamicResource, but this isn't recommended unless the resource's link might actually change at run time (see What's the difference between StaticResource and DynamicResource in WPF? )
An easier solution:
If you just want to hard-code the style in, instead of reference the foreground brush externally, then you could change the line:
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
to:
<Setter Property="Foreground" Value="[SOME COLOR]"/>
To get rid of the need to create a separate brush object for your font.

Styling of ListBoxItem Not Working

I'm attempting to style the ListBoxItems within my listbox but the content of the ListBoxItem does not display and any change in colours are not apparent. The only thing working is the "border bottom" that I've applied to the bottom of each list item.
<Style x:Key="ListItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="#FF66AFDE" BorderThickness="0 0 0 1" />
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use a panel/container/decorator in the ListBoxItem control template to set the background color. (It seems that the logic for setting the selection background color will interfere with attempts to control its background color.)
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
Name="PART_Border"
Focusable="true"
Background="{TemplateBinding Background}"
BorderBrush="#FF66AFDE"
BorderThickness="0 0 0 1"
>
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter
Property="Background"
Value="Red"
TargetName="PART_Border"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Also note, that Border.Focusable is by default false. If setting it to true doesn't work (i admit, i haven't tested), use a different container control instead of Border.
Also, if the content you will show has any controls receiving focus (such as buttons or text fields), the trigger might not work as expected, because the Border might not have the focus when a control of the content has the focus. Also, tabbing from control to control might exhibit unexpected behaviour. If you have to deal with such a situation, try to handle the trigger in an ItemTemplate instead.
Regarding the ContentPresenter not showing anything: Depending on the type of the elements in the ItemsSource, you might need to define a ListBox.ItemTemplate (or ListBox.ItemTemplateSelector), otherwise ContentPresenter might not know what to display.
Try this
<Style x:Key="ListItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderBrush="#FF66AFDE" BorderThickness="0 0 0 1" x:Name="border">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="border" Property="Background" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I hope this will help

Flat button in WPF - trigger not firing

I wanted to restyle my buttons to be more flat so I have created two styles; first for ToggleButton that derives from ToolBar.ToggleButtonStyleKey and second for Buttonthat derives from ToolBar.ButtonStyleKey.
It worked great - the buttons are now toolbar-like and flat. Second thing I wanted is to have Background property to be transparent when user hovers the cursor over the control. So to achieve that I defined a simple trigger that sets the Background to Transparent on IsMouseOver event. It worked for ToggleButton, however, the same trigger didn't work for Button(the background was not affected at all).
Does anyone know why this trigger works great for ToggleButton and does not work for Button? I did expect the same behavior since both styles are from the same family.
Below is the full code.
<Window x:Class="WpfButtonsTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="FlatToggleButton" TargetType="ToggleButton"
BasedOn="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="FlatButton" TargetType="Button"
BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<ToggleButton Style="{StaticResource FlatToggleButton}">
I am Toggle Button
</ToggleButton>
<Button Style="{StaticResource FlatButton}">
I am Button
</Button>
</StackPanel>
</Grid>
</Window>
I had a look using Snoop (a very handy program for inspecting WPF ) and it looks like the template which you're using as a basis, ToolBar.ButtonStyleKey, has a trigger which selects a solid Brush for the background of a Border element within the Button (in thise case when IsMouseOver is true).
Your local style trigger is successfully setting the background of the Button element to transparent (or rather, keeping it transparent), but the Border background is unaffected, so you'll still see the highlighting behaviour.
Border Background:
Button Background:
I think you'll have to define a ControlTemplate to get the button you're after, I've grabbed this from one of the ToolBar samples included in Kaxaml (a nice XAML editor). It's a reasonable facsimile of the Toolbar bas button style, with a few bits removed, it may behave as you want, or you might need to tweak it depending on your desired behaviour.
I've left the IsPressed trigger in place, you may want to remove it, or add additional triggers.
<Style x:Key="ToolBarButtonBaseStyle" TargetType="{x:Type ButtonBase}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border
x:Name="Border"
BorderThickness="1"
Background="Transparent"
BorderBrush="Transparent">
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<!-- Additional triggers removed, e.g "IsMouseOver" -->
<!-- You may not want any at all -->
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
<Setter TargetName="Border" Property="BorderBrush" Value="#606060" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I see that the both FlatToggleButton and FlatButton styles already have Background as Transparent
<Setter Property="Background" Value="Transparent"/>
When the triggers is fired on IsMouseOver and set the Background again to Transparent you will not see any difference
So what you need to do is one of these options :
Change both styles so that the Background is something else than Transparent
Change the trigger so it sets the Background to something else than Transparent

Categories