I have custom control where i want to show some items.
In generic.xaml defined style for custom control:
<Style TargetType="local:Custom">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:Customl">
<!-- Root Grid-->
<Grid x:Name="CustomLayout"
Background="Black">
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And i set to C#
[TemplatePart(Name = "CustomLayout", Type = typeof(Grid))]
[StyleTypedProperty(Property = "ChildItemStyle", StyleTargetType = typeof(Control))]
public class GaugeControl : Control
Everything working fine excepts style for child items
defined in
generic.xaml:
<Style TargetType="{x:Type Control}">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control}">
<!-- Root Grid-->
<Grid x:Name="LayoutRoot"
Background="Red">
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Custom control with attribute
[StyleTypedProperty(Property = "ChildItemStyle", StyleTargetType = typeof(Control))]
And i have ChildItemStyle DependencyProperty in my custom control but its always null.
How can i get this Style property and whats wrong i am doing?
I found solution and bug in my code.
I just add setter to my <Style TargetType="local:Custom"> definition and with help of setter set ChildItemStyle which i want.
Related
I have created custom control and a default style for it.
My XAML is simple:
<Style TargetType="{x:Type local:MyControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border CornerRadius="10" BorderThickness="1" Background="Transparent" BorderBrush="Black"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I connect to this style using DefaultStyleKey:
DefaultStyleKey = typeof(MyControl);
And it works. But now I want to create other style for my control. It's because my control can have some modes defined as enums, like:
public enum ControlMode
{
Mode1,
Mode2
}
Now, when my control is in Mode1 I want it to have its default style. But when it's in Mode2 I want it to have another style, like:
<Style TargetType="{x:Type local:MyControl}" x:Key"styleForMode2>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness="1" Background="White" BorderBrush="Black"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I achieve that? DefaultStyleKey works only for type name, so the only thing I came up with is to create another class for my control: MyControlWithMode2. But I'm sure there is more proper way. Right?
(this is library not an application, so I cannot use application's resources)
Assuming your control has a Mode property, the default Style could declare Triggers to set different ControlTemplates for different modes:
<Style TargetType="local:MyControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border CornerRadius="10" BorderThickness="1"
Background="Transparent" BorderBrush="Black"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Mode" Value="Mode2">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness="1" Background="White"
BorderBrush="Black"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
I'm styling hyperlinks that appear within a border with the style "FooterPanel" as follows:
<Style x:Key="FooterPanel" TargetType="{x:Type Border}">
<Style.Resources>
<Style TargetType="{x:Type Hyperlink}">
<Setter Property="Foreground" Value="{StaticResource FooterPanelLinkBrush}"/>
</Style>
</Style.Resources>
</Style>
I also now have created a style to create a button as a hyperlink (so I can get properties such as IsDefault and IsCancel on a hyperlink):
<Style x:Key="LinkButton" TargetType="{x:Type Button}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Hyperlink Command="{TemplateBinding Command}" CommandParameter="{TemplateBinding CommandParameter}">
<Run Text="{TemplateBinding Content}"/>
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Normal hyperlinks within FooterPanel receive the FooterPanelLinkBrush foreground, but if I use LinkButton within a FooterPanel, the style is not applied. Is there a way to get the ControlTemplate to inherit the styles within the FooterPanel instead of any global hyperlink styles?
Edit:
According to this answer https://stackoverflow.com/a/9166963/2383681 there is special handling that means the Hyperlink won't receive the styles defined in the FooterPanel as it's not derived from Control.
I'm not sure what I'm trying to do is therefore possible without some code-behind, so I think I'm just going to workaround this and create a new style for FooterPanelLinkButton and explicitly reference this for the buttons that are in a footer panel. It would be interesting to know if this is possible however without doing that.
You can create a separate Style for the HyperLink:
<Style x:Key="FooterPanelLink" TargetType="{x:Type Hyperlink}">
<Setter Property="Foreground" Value="{StaticResource FooterPanelLinkBrush}"/>
</Style>
And then use this Style in the Resources of the FooterPanel and LinkButton styles in the following way:
<Style x:Key="FooterPanel" TargetType="{x:Type Border}">
<Style.Resources>
<Style TargetType="Hyperlink" BasedOn="{StaticResource FooterPanelLink}" />
</Style.Resources>
</Style>
<Style x:Key="LinkButton" TargetType="{x:Type Button}">
<Style.Resources>
<Style TargetType="Hyperlink" BasedOn="{StaticResource FooterPanelLink}" />
</Style.Resources>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Hyperlink Command="{TemplateBinding Command}" CommandParameter="{TemplateBinding CommandParameter}">
<Run Text="{TemplateBinding Content}"/>
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This way the HyperLink inside the LinkButton will use the color you assigned in the FooterPanelLink style.
I have a WPF menu:
XAML:
<Style x:Key="{x:Type ContextMenu}" TargetType="{x:Type ContextMenu}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Background="#FF171616" CornerRadius="5" BorderBrush="DarkGray" BorderThickness="5" Opacity="0.0">
<StackPanel ClipToBounds="True" Orientation="Vertical" IsItemsHost="True" Margin="5,4,5,4"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Am I using the correct x:Type ContextMenu to alter the drop down visualization? The menu item visual is altered because I've manually changed the style. But it is the context drop down on which I want to apply visuals.
How can I modify the context drop down itself?
Here is a paint sample of what I'm after:
To modify style for menu, you need to override Menu style.
Like below:
<Style TargetType="{x:Type Menu}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="#FF171616" />
</Style>
Edit: you can actually modify the whole template also, if you like. But I think these properties should get you the visualization you are looking for.
I keep going around in circles on this data trigger so it is not working...
I have a button that has a border for a default dropshadow. However, I want to create a dep property to be used to toggle this. Yet, I never get to the point where the effect is being set.
<Style x:Key="RoundedButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrls:RoundedButton">
<Grid>
<Border>
<Border.Style>
<Style TargetType="ctrls:RoundedButton">
<Style.Triggers>
<Trigger Property="IsDropShadowVisible" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="1"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
This is based off of a button, but is implemented as the custom user control...This is legacy code...
What I have here works
Did this in a new WPF window. No other code-behind than what you see here.
<Window.Resources>
<Style TargetType="{x:Type local:ShadowButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ShadowButton}">
<Button Name="Button"></Button>
<ControlTemplate.Triggers>
<Trigger Property="IsDropShadowVisible" Value="True">
<Setter TargetName="Button" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="1"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<!-- snip code -->
<local:ShadowButton Height="10" Width="10" IsDropShadowVisible="true"/>
Code-behind:
public class ShadowButton : Button
{
public DependencyProperty IsDropShadowVisibleProperty =
DependencyProperty.Register("IsDropShadowVisible", typeof(Boolean), typeof(ShadowButton), new PropertyMetadata(false));
public Boolean IsDropShadowVisible
{
get { return (Boolean)GetValue(IsDropShadowVisibleProperty); }
set { SetValue(IsDropShadowVisibleProperty, value); }
}
}
I have a context menu bound to a data source. For this context menu I have a DataTrigger to display a separator if the databound object has a value of "True" for the Separator property. This works well however it doesn't seem to pick up my global style for separators that I have in my application. The new separator appearance is different than the rest of my menu's. Is there a way to have it use the global style?
Below is the ContextMenu definition:
<ContextMenu
x:Key="ActionMenu"
ItemsSource="{Binding Source={StaticResource ActionMenuSource}}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Separator}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static
MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
Here are my global values for defining the Separator.
<Style x:Key="{x:Static MenuItem.SeparatorStyleKey}" TargetType="{x:Type Separator}">
<Setter Property="Template" Value="{DynamicResource tmp_ManhMenuItemSeparator}"/>
</Style>
<ControlTemplate x:Key="tmp_ManhMenuItemSeparator" TargetType="{x:Type Separator}">
<Rectangle Name="SepRect" StrokeThickness="1" Stroke="White"/>
</ControlTemplate>
To make a style global the key needs to be the same as the TargetType which is clearly not the case in your sample. Change your key to "{x:Type Separator}" and see if that works for you. You can also merge your two snippets together unless you have a particular need to split them out, e.g.
<Style x:Key="{x:Type Separator}" TargetType="{x:Type Separator}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Separator}">
<Rectangle Name="SepRect" StrokeThickness="1" Stroke="White"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Once you have done that you can probably strip down the first block of code. It looks like you are trying to make the menu manually use the style. If you make it global you don't need to do that, e.g.
<ContextMenu x:Key="ActionMenu" ItemsSource="{Binding Source={StaticResource ActionMenuSource}}"/>