[英]Setting the style on a xaml button programmatically fails
我正在控制。 該控件需要使用來自外部源的輸入來設置樣式。 我一直在尋找解決方案,並發現了一些不會破壞代碼的解決方案。 但是,它不是在樣式按鈕。 我將樣式設置為資源。 在按鈕上對其應用引用。 初始化內容,但不應用樣式。
public MainPage()
{
//String[] settings = Application.Current.Resources["settings"].ToString().Split(new Char[1] { '\u003A' });
String[] settings = "_icons/pngp/2933.png:1:ff0000:Select files from disk...:36:36".Split(new Char[1] { '\u003A' });
//style the dialog button
ImageBrush image = new ImageBrush();
image.ImageSource = new BitmapImage(new Uri(settings[0], UriKind.Relative));
Button dialogButton = new Button();
dialogButton.Background = image;
var styleOverride = new Style(typeof(Button)) ;
styleOverride.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(0)));
styleOverride.Setters.Add(new Setter(Border.BorderBrushProperty, colorConverter(settings[2])));
styleOverride.Setters.Add(new Setter(Border.BorderThicknessProperty, new Thickness(double.Parse(settings[1]))));
this.Resources.Add("key", styleOverride);
dialogButton.Style = this.Resources["key"] as Style;
dialogButton.Height = double.Parse(settings[4]);
dialogButton.Width = double.Parse(settings[5]);
//attach the click handler;
dialogButton.Click += dialogButton_Click;
ToolTip tooltip = new ToolTip();
tooltip.Content = settings[3];
ToolTipService.SetToolTip(dialogButton, tooltip);
this.InitializeComponent();
this.LayoutRoot.Children.Add(dialogButton);
this.LayoutRoot.Drop += this.Canvas_Drop;
}
我已經硬編碼了settings
字符串。 通常,這是動態的,並且來自外部資源。 問題是為什么dialogButton.Style = this.Resources["key"] as Style;
沒有應用所需的樣式效果?
該圖像現在顯示結果(左)和所需的效果(右)。 無圓角邊框和不同的邊框顏色。 不,紅色不會是最終的顏色。 這是用於調試。
您的代碼中有兩個問題。
首先,您要使用Border.BorderBrushProperty
和Border.BorderThicknessProperty
,它們不是Button
控件中的依賴項屬性。 您應該將它們分別更改為Button.BorderBrushProperty
和Button.BorderThicknessProperty
,如下所示-
styleOverride.Setters.Add(new Setter(Button.BorderBrushProperty, colorConverter(settings[2])));
styleOverride.Setters.Add(new Setter(Button.BorderThicknessProperty, new Thickness(double.Parse(settings[1]))));
第二個問題是Button
控件中沒有CornerRadius
依賴項屬性。 因此,您不能簡單地將其更改為Button.CornerRadiusProperty
。
解決方法是,在頁面內定義一個本地Button
Style
,然后使用TemplateBinding
將Border
的CornerRadius
(在Button
的ControlTemplate
內)綁定到Tag
依賴項屬性。 這部分很容易在xaml中完成。
CornerRadius="{TemplateBinding Tag}"
然后,您只需要將Style
用作替代Style
的BaseOn
並更新Tag
屬性即可。
var styleOverride = new Style(typeof(Button))
{
BasedOn = (Style)this.Resources["ButtonStyle1"]
};
styleOverride.Setters.Add(new Setter(Button.TagProperty, new CornerRadius(0)));
這里附有完整的xaml Button
Style
。
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
<ColorAnimation Duration="0" To="#F2FFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#CCFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#7FFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="#FF6DBDD1" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
<ColorAnimation Duration="0" To="#D8FFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#C6FFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#8CFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#3FFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="White" CornerRadius="{TemplateBinding Tag}">
<Grid Background="{TemplateBinding Background}" Margin="1" d:IsHidden="True">
<Border x:Name="BackgroundAnimation" Background="#FF448DCA" Opacity="0" d:IsHidden="True"/>
<Rectangle x:Name="BackgroundGradient" d:IsHidden="True">
<Rectangle.Fill>
<LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#F9FFFFFF" Offset="0.375"/>
<GradientStop Color="#E5FFFFFF" Offset="0.625"/>
<GradientStop Color="#C6FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" d:IsHidden="True"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我測試了代碼,結果完全符合您的預期。
希望這可以幫助!
不要在代碼后面直接設置樣式:
dialogButton.Style = this.Resources["key"] as Style;
但是使用SetValue
方法:
var style = this.Resources["key"] as Style; // or this.TryFindResource("key") as Style;
dialogButton.SetValue(StyleProperty, style);
似乎已應用樣式,但紅色邊框覆蓋了png。 嘗試注釋掉以下行:
/* styleOverride.Setters.Add(new Setter(Border.BorderBrushProperty, colorConverter(settings[2]))); */
現在,背景圖像變得可見。 也許解決方案是將圖像尺寸調整為40x40像素並留有邊距?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.