combobox template problems wpf - c#

I've created template for combobox but it has strange view, data is not displaying:
Here is XAML code:
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border Background="{TemplateBinding Background}" x:Name="Bd" BorderBrush="Gray" BorderThickness="2" CornerRadius="2">
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" TargetName="Bd"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="BorderBrush" Value="Blue" TargetName="Bd"/>
<Setter Property="BorderThickness" Value="2"/>
</Trigger>
<Trigger Property="IsFocused" Value="false">
<Setter Property="BorderBrush" Value="Gray" TargetName="Bd"/>
<Setter Property="BorderThickness" Value="2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What i missed here?

Your template creates near to nothing which makes the default one work, i.e. there is no items popup, and there is no ContentPresenter for the selected item either. Have a look at the default template and you will see exactly what you are missing (Here is a question explaining where to get them).

Related

Multiple styles and content on one button

I have a HomePage with a number of buttons on that I am trying to get to do a couple of things. Firstly, I have a Style in a ResourceDictionary that dictates the overall 'look and feel' of the buttons. It looks like this:
<Style TargetType="Button" x:Key="HomeButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#06658D"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</Trigger>
</Style.Triggers>
</Style>
Nothing too complicated, however I want the MouseOver effect to persist after being clicked. So now I am looking at doing something like this:
<Button Grid.Row="0" Style="{StaticResource HomeButton}" Content="Contacts">
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding ContactsClicked}" Value="True">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button>
I'll bind the command element of the Button to set ContactsClicked = true and reset this when another button is pressed. However, I get the error saying that Content is set multiple times.
Is it possible to have an overall Style of the Button set, as well as a 'Clickedstyle and to have aTextBlockdisplaying text on the button all at once or am I approaching this wrong? I am trying to not have an individual overall style for every singleButton`as that's a lot of repeated code.
For clarity this is what I am aiming for:
I've managed to find a solution myself, instead of using a Button us a ToggleButton instead:
<Style TargetType="ToggleButton" x:Key="HomeButton">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#06658D"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="#06658D"/>
</Trigger>
</Style.Triggers>
</Style>
I would add this as a comment but im not allowed.
If your goal is that the button will stay selected after it is clicked, why not use a RadioButton? A RadioButton has a built-in property called IsChecked but will also remain "Checked" or "Selected" even after multiple clicks.
Of course you can define the behavior and the styles in a similar manner, create a simple Trigger on the property IsChecked.
If more explanation is needed, just say so.

prefix "style" does not map to a namespace

I've looked through every answer here on StackOverflow but nothing fixed my problem.. I have following style written in App.xaml for my buttons. And this style is linked to my class in another assembly where data is being taken from.
This WORKS at runtime, but it's giving me a hard time inside designer.
There are no errors in the style itself, the error begings with ControlTemplate.
<Style x:Key="HeaderBTN" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Width" Value="36" />
<Setter Property="Padding" Value="5" />
<Setter Property="Background" Value="{Binding Path=(style:AppStyle.AccentMain)}" />
<Setter Property="Foreground" Value="{Binding Path=(style:AppStyle.AccentText)}" />
<Setter Property="FontSize" Value="20" />
<Setter Property="FontFamily" Value="Times New Roman" />
<Setter Property="Margin" Value="0" />
<Setter Property="DockPanel.Dock" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border" BorderThickness="0" CornerRadius="0" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding Path=(style:AppStyle.AccentHover)}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{Binding Path=(style:AppStyle.AccentButtonDown)}" />
<Setter Property="Foreground" Value="{Binding Path=(style:AppStyle.AccentTextDown)}" />
</Trigger>
<Trigger Property="IsDefaulted" Value="True">
<Setter Property="Background" Value="#3b3b3b" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#505050" />
<Setter Property="Foreground" Value="#A7A7A7" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is there any alternative to this that would leave everything functional? It's important that these resources are dynamic because Users have to be able to change the theme.
Any help is appreciated.
P.S. I use Visual Studio 2013 Professional with Update 5

How To Style Button's Hover And Click Foreground?

I am new to Styles and not sure on the best way to create a Button style to change the Foreground of IsMouseOver and IsPressed. I used a Border for a template because it has a CornerRadius and background and border properties. But Border does not have a Foreground property. Using Button as the template doesn't work well since the default look isn't being overridden.
What is a better way to style a Button template with Foreground behavior? Maybe using a label inside the border?
Here is the App.xaml:
<Application.Resources>
<Style TargetType="Button" x:Key="MyButton">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Black" />-->
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="DarkGray" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="Black" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Red" />-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And the xaml:
<StackPanel HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100">
<Button Content="Button" Height="41" Style="{DynamicResource MyButton}"/>
</StackPanel>
You need to move your Triggers from the ControlTemplate to the Style. Something like this:
<Style TargetType="Button">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FFDADADA" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="DarkGray" />
</Trigger>
</Style.Triggers>
</Style>
What you can do is set attached property of TextElement on the Border and like that every text element within your Border will be of that colour:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<Setter TargetName="shortcutbutton" Property="TextElement.Foreground" Value="White"/>
</Trigger>
...
</ControlTemplate.Triggers>

WPF ListBox turn off hover effect

I've found and tried many solutions on the internet which should allow me to disable the hover effect of my WPF ListBox but none of them seemed to work for me. This screenshot shows the hover effect I'd like to hide or get rid of:
This is (a simplified version) of the XAML code I currently have:
<ListBox ItemsSource="{Binding Logs}" Grid.Column="1" Width="800" Height="100" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="Control.Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
However, it doesn't seem to work for me for a reason or another. Could my parent ListBox (the one in the background) or another control override it's child's style by any chance? (I already tried to override the parents style as well)
Modify the default style of a ListBoxItem
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" 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="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Just add a trigger
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
Getting rid of the blue devil?
If you have no need to click on your items the following will make it disappear, the highlighting on mouse hover:
<ListBox IsHitTestVisible="False">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsTabStop" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Glad that" />
<ListBoxItem Content="they are over" />
<ListBoxItem Content="the days of the blue devil" />
</ListBox>

How to tell if text it ContentProvider has been edited?

I've got DataGrid with several DataGridTextColumn's, one of which is editable.
I need to intercept TextChanged event for the cell that is being edited.
I've tried editing style and adding
<EventSetter Event="TextChanged" Handler="TaskDescription_TextChanged"/>
but I'm getting
Cannot find the Style Event 'TextChanged' on the type 'System.Windows.Controls.DataGridCell'
Is there an easy way to get notified of the text change in DataGridTextColumn except by Two-Way binding?
Here's the XAML code:
<Style x:Key="CenteredTextColumn" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Height="30">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter VerticalAlignment="Center" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource SelectedCellBackground}"/>
<Setter Property="Foreground" Value="White"/>
<!--<Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>-->
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<!--<Setter Property="BorderBrush" Value="{DynamicResource {x:Static DataGrid.FocusBorderBrushKey}}"/>-->
</Trigger>
<Trigger Property="IsEditing" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
and the EventSetter:
<Style x:Key="ProjectInfoEditeableCell" TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource CenteredTextColumn}">
<EventSetter Event="TextChanged" Handler="TaskDescription_TextChanged"/>
</Style>

Categories