is there any way to override a single role style of MenuItem? I know the way to override the IsHighlighted color of MenuItem is to override the ContentTemplate. What i want is to override the ContentTemplate for Role "SubmenuItem"
<Style x:Key="ActionMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template" Value="{StaticResource SubmenuItemTemplateKey2}" />
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Padding" Value="7,2,8,3" />
<Setter Property="Template" Value="???" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="7,2,8,3" />
<Setter Property="Template" Value="???" />
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Padding" Value="2,3,2,3" />
<Setter Property="Template" Value="???" />
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Padding" Value="2,3,2,3" />
</Trigger>
</Style.Triggers>
</Style>
The {StaticResource SubmenuItemTemplateKey2} is my override ContentTemplate. For the other roles i want use the default templates of MenuItem. Is there any way to do it?
Best regards
Lutze
You're trying to override all the menu items and next trying to override it again (to set it back to default style). In this case you just need to override the menu item with role of SubmenuItem, so the code can be just like this:
<Style x:Key="ActionMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="HorizontalContentAlignment"
Value="{Binding Path=HorizontalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding Path=VerticalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Padding" Value="7,2,8,3" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="7,2,8,3" />
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Padding" Value="2,3,2,3" />
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Padding" Value="2,3,2,3"/>
<!-- override here -->
<Setter Property="Template"
Value="{StaticResource SubmenuItemTemplateKey2}"/>
</Trigger>
</Style.Triggers>
</Style>
Otherwise (following your original approach), we may need some dummy MenuItem element which has the default style. Then we can Bind the Template of whatever items to the Template of that dummy element to restore their default style.
Related
I have some runtime generated WPF buttons that I need to style using code behind. I have the Style below in a code behind variable ( Style Editstyle = Application.Current.Resources[x] as Style;)
How would I change the DynamicResource of the values in the Trigger section from codebehind?
Like style.Trigger.IsFocused.Background = bitmapX;
Also style.Key="NewStyleCopy1";
<Style x:Key="INIT_A" TargetType="Button">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Background" Value="{DynamicResource back}" />
<Setter Property="Foreground" Value="{DynamicResource fore}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderBrush="{DynamicResource stroke}"
BorderThickness="1"
Padding="4,2"
CornerRadius="0"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{DynamicResource altback}" />
<Setter Property="Foreground" Value="{DynamicResource altfore}" />
<Setter TargetName="border" Property="BorderBrush" Value="{DynamicResource altstroke}" />
<Setter Property="Button.Effect" Value="{DynamicResource a_hbtnglow}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource altback}" />
<Setter Property="Foreground" Value="{DynamicResource altfore}" />
<Setter TargetName="border" Property="BorderBrush" Value="{DynamicResource altstroke}" />
<Setter Property="Button.Effect" Value="{DynamicResource a_hbtnglow}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource altback}" />
<Setter Property="Foreground" Value="{DynamicResource altfore}" />
<Setter TargetName="border" Property="BorderBrush" Value="{DynamicResource altstroke}" />
<Setter Property="Button.Effect" Value="{DynamicResource a_hbtnglow}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is usually done in XAML by defining a Trigger for each state:
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
You can make use of the Style.BasedOn property to extend a particular Style, for example a default Style for all Button elements. This way you can create a more specific Style that includes all attributes of the base Style:
<Style x:Key="DefaultButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Orange" />
</Style>
<Style x:Key="GeneratedButtonsStyle"
BasedOn="{StaticResource DefaultButtonStyle}"
TargetType="Button">
<!-- Override the base Style value -->
<Setter Property="Background" Value="Yellow" />
<!-- Extend the base Style -->
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
I ended up copying the style and edited the properties.
I appreciate all your suggestions.
var xu = styleCopy("ButtonAA");
Trigger t = new Trigger();
t.Property = Button.IsMouseOverProperty;
t.Value = true;
Setter setter = new Setter();
setter.Property = Button.BackgroundProperty;
setter.Value = Brushes.Blue;
t.Setters.Add(setter);
xu.Triggers.Add(t);
btn.Style = xu;
I am developing a WPF Application using Mahapps.Metro library.
There is a DataGrid where I want to use a ContextMenu on the added rows, for that I am defining this in datagrid resources
<DataGrid.Resources>
<ContextMenu x:Key="RowMenu"
DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Borrar detalle" Click="delete_Click" />
<MenuItem Header="Editar detalle" Click="edit_Click" />
</ContextMenu>
</DataGrid.Resources>
and adding that context menu in the rowstyle
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
The problem with this is that when user clicks on the row, it seems to disappear (the font color turns white).
I tried adding the following to the rowstyle but it does not seems to work.
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="LightSkyBlue"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="LightSkyBlue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
MY last option is to use the contextmenu in the grid instead rows, but I want to know if there is something I can do to make this work.
Hope you can help, thanks.
You should use based-on feature on your defined style:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
I got this style for my button already:
<Style x:Key="ControlButtons">
<Setter Property="Button.Height" Value="25" />
<Setter Property="Button.Width" Value="60" />
<Setter Property="Button.Background" Value="#FF373E48" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.Margin" Value="3,15,0,5" />
<Setter Property="Button.HorizontalAlignment" Value="Left" />
<Setter Property="Button.VerticalAlignment" Value="Center" />
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderThickness="0.5" BorderBrush="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#FF3D4959" />
<Setter Property="Foreground" Value="#FF7B7F84" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3A3F4C" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FF373E48" />
<Setter Property="Foreground" Value="#FF000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now i wanted to change the border of it when the button is pressed and i can't figure out how it have to put in the code there...
I found this already WPF changing button background on click but i really can't seem to find a way to incoorperate it into my code...
Any help appreciated!
Edit:
I changed my style to this and now it's working:
<Style x:Key="ControlButtons">
<Setter Property="Button.Height" Value="25" />
<Setter Property="Button.Width" Value="60" />
<Setter Property="Button.Background" Value="#FF373E48" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.Margin" Value="3,15,0,5" />
<Setter Property="Button.HorizontalAlignment" Value="Left" />
<Setter Property="Button.VerticalAlignment" Value="Center" />
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="brdbutton" Background="{TemplateBinding Background}" BorderThickness="0.5" BorderBrush="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#FF3D4959" />
<Setter Property="Foreground" Value="#FF7B7F84" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3A3F4C" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FF373E48" />
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="Border.BorderThickness" Value="0.5" TargetName="brdbutton" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="brdbutton" Storyboard.TargetProperty="(Button.BorderBrush).(SolidColorBrush.Color)" To="LawnGreen"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You must change your code as what i edited below:
<Style x:Key="ControlButtons">
<Setter Property="Button.Height" Value="25" />
<Setter Property="Button.Width" Value="60" />
<Setter Property="Button.Background" Value="#FF373E48" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.BorderBrush" Value="White" />
<Setter Property="Button.Margin" Value="3,15,0,5" />
<Setter Property="Button.HorizontalAlignment" Value="Left" />
<Setter Property="Button.VerticalAlignment" Value="Center" />
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderThickness="0.5" BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#FF3D4959" />
<Setter Property="Foreground" Value="#FF7B7F84" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3A3F4C" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FF373E48" />
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I've done in this way:
<Style x:Key="ControlButtons">
<Setter Property="Button.Height" Value="25" />
<Setter Property="Button.Width" Value="60" />
<Setter Property="Button.Background" Value="#FF373E48" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.Margin" Value="3,15,0,5" />
<Setter Property="Button.HorizontalAlignment" Value="Left" />
<Setter Property="Button.VerticalAlignment" Value="Center" />
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="brdbutton" Background="{TemplateBinding Background}" BorderThickness="0.5" BorderBrush="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#FF3D4959" />
<Setter Property="Foreground" Value="#FF7B7F84" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3A3F4C" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FF373E48" />
<Setter Property="Foreground" Value="#FF000000" />
<Setter Property="Border.BorderBrush" Value="Yellow" TargetName="brdbutton" />
<Setter Property="Border.BorderThickness" Value="3" TargetName="brdbutton" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Give the Border element an x:Name and specify the TargetName of the Setter:
<Style x:Key="ControlButtons">
<Setter Property="Button.Height" Value="25" />
<Setter Property="Button.Width" Value="60" />
<Setter Property="Button.Background" Value="#FF373E48" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.Margin" Value="3,15,0,5" />
<Setter Property="Button.HorizontalAlignment" Value="Left" />
<Setter Property="Button.VerticalAlignment" Value="Center" />
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="0.5" BorderBrush="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#FF3D4959" />
<Setter Property="Foreground" Value="#FF7B7F84" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3A3F4C" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<!-- change the properties of the Button itself:-->
<Setter Property="Background" Value="#FF373E48" />
<Setter Property="Foreground" Value="#FF000000" />
<!-- change the properties of the Border element in the template:-->
<Setter TargetName="border" Property="BorderBrush" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have this Dynamic Resource to set my TextBox's styles:
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="FontSize" Value="30"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontFamily" Value="CenturyGothicRegual"/>
<Setter Property="Foreground" Value="#FF5B5B5B"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="BorderBrush" Value="#FF5B5B5B"/>
<!--<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style x:Name="ActiveStyle" TargetType="{x:Type TextBox}">
<Setter Property="BorderBrush" Value="Black"/>
</Style>
</Setter.Value>
</Setter>-->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="10"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="Pink" />
<Setter Property="BorderThickness" Value="15"/>
</Trigger>
</Style.Triggers>
</Style>
And the textbox that uses it:
<TextBox Grid.Row="2" Grid.Column="1" Margin="2,2,2,2" Style="{DynamicResource TextBoxStyle}"
FontSize="30" Text="asdasd" HorizontalContentAlignment="Left" VerticalContentAlignment="Center"
FocusVisualStyle="{StaticResource TextBoxStyle}">
</TextBox>
Again the problem is that when I hover over my mouse or click in the textbox, the border gets the default blueish colour. However the borderthickness does change when I set them (ugly that way but needed to debug). So how to get around this issue?
You need to override the ControlTemplate of the Button because there is a trigger in the default template that sets the BorderBrush property to a hardcoded value on mouse over:
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Setter Property="FontSize" Value="30"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FontFamily" Value="CenturyGothicRegual"/>
<Setter Property="Foreground" Value="#FF5B5B5B"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="BorderBrush" Value="#FF5B5B5B"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="10"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="Pink" />
<Setter Property="BorderThickness" Value="15"/>
</Trigger>
</Style.Triggers>
</Style>
I wanted to create a button-Template that only reacts to the click event and is never shown in any way (i.E. no borderstyle changes on click, mouseover or something the like).That works fine, but if I put a button with this template in a Grid, the gridpart it is in, is not clickable completly, only where the content of the button is.How can I make my template the way its normally filling a gridpart completly?
<Style TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border">
<ContentPresenter RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
</Trigger>
<Trigger Property="IsDefaulted" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
<Setter Property="Foreground" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>