Reputation: 883
I am trying to create a C# version of a XAML Style, but I'm struggling to add the ContentPresenter/ContentTemplate
and VisualStateManagers
. Surely this shouldn't be difficult, but it is proving so.
E.g. how would I create a C# version of this..
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
<Setter Property="BorderThickness" Value="0,0,0,2" />
<Setter Property="Padding" Value="12,8,12,8" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource TextStyleLargeFontSize}" />
<Setter Property="UseSystemFocusVisuals" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid"
Background="{TemplateBinding Background}">
<Border x:Name="FocusOuterRectangle"
Margin="-3,-3,0,0"
BorderBrush="{ThemeResource SystemControlForegroundTransparentBrush}"
BorderThickness="3,3,3,1">
<ContentPresenter x:Name="ContentPresenter"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
FontSize="{TemplateBinding FontSize}"
TextWrapping="WrapWholeWords" />
</Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource myButtonBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource myBlackBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource myWhiteBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusOuterRectangle"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource SystemControlForegroundTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource myButtonHoverBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource myBlackBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource myWhiteBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusOuterRectangle"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{StaticResource SystemControlForegroundTransparentBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="RootGrid" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
So far I've got this:
var style = new Style();
style.TargetType = typeof(Button);
style.Setters.Add(new Setter(Button.BackgroundProperty, Brushes.MyButtonBrush));
style.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.MyWhiteBrush));
style.Setters.Add(new Setter(Button.BorderBrushProperty, Brushes.MyBlackBrush));
style.Setters.Add(new Setter(Button.BorderThicknessProperty, new Thickness(0, 0, 0, 2)));
style.Setters.Add(new Setter(Button.PaddingProperty, new Thickness(12, 8, 12, 8)));
style.Setters.Add(new Setter(Button.HorizontalAlignmentProperty, HorizontalAlignment.Left));
style.Setters.Add(new Setter(Button.VerticalAlignmentProperty, VerticalAlignment.Center));
style.Setters.Add(new Setter(Button.FontFamilyProperty, FontFamily.XamlAutoFontFamily));
style.Setters.Add(new Setter(Button.FontWeightProperty, FontWeights.Normal));
style.Setters.Add(new Setter(Button.FontSizeProperty, TextStyleLargeFontSize));
style.Setters.Add(new Setter(Button.UseSystemFocusVisualsProperty, false));
var controlTemplate = new ControlTemplate { TargetType = typeof(Button) };
var contentPresenter = new ContentPresenter
{
Name = "ContentPresenter",
Padding = new Thickness(0, 0, 0, 2),
HorizontalContentAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Center,
BorderBrush = Brushes.MyBlackBrush,
BorderThickness = new Thickness(0, 0, 0, 2),
FontSize = TextStyleLargeFontSize,
TextWrapping = TextWrapping.WrapWholeWords
};
But I'm unsure how to add the ContentPresenter
to the ControlTemplate
, or to create a Grid
that contains the ContentPresenter
. Then I'm unsure how to begin creating the VisualStateGroups
etc.
Many thanks for any help.
Upvotes: 1
Views: 66
Reputation: 39082
I don't think it is possible to write equivalent code in the code-behind. In WPF the ControlTemplate
had a VisualTree
property that allowed to set it in code-behind and you also could use FrameworkElementFactory
to create subclasses of FrameworkTemplate
such as ControlTemplate
or DataTemplate
, but these options were incomplete and didn't provide all of the XAML flexibility. Instead, you can use the XamlReader
class to parse XAML code from a string
at runtime. This way you may be able to create it in code-behind, but I don't see many reasons for doing so over just using the XAML code you already have.
Upvotes: 1