C# UWP根据类按钮扩展中的ButtonType属性更改按钮样式的最佳方法是什么?

C# UWP根据类按钮扩展中的ButtonType属性更改按钮样式的最佳方法是什么?,c#,.net,xaml,uwp,C#,.net,Xaml,Uwp,我正在尝试使用如下ButtonType扩展button类: public class MyButton : Button { public MyButton() { } public string ButtonType { get { return (string)GetValue(ButtonTypeProperty); } set {SetValue(ButtonTypeProperty

我正在尝试使用如下ButtonType扩展button类:

public class MyButton : Button 
{
     public MyButton()
     {
     }
     public string ButtonType
     {
         get { return (string)GetValue(ButtonTypeProperty); }
         set
         {SetValue(ButtonTypeProperty, value);}
     }
     // Using a DependencyProperty as the backing store for ButtonType.  This enables animation, styling, binding, etc...
     public static readonly DependencyProperty ButtonTypeProperty =
         DependencyProperty.Register("ButtonType", typeof(string), typeof(MyButton), new PropertyMetadata(0));
}

我的按钮模板:

                <ControlTemplate TargetType="controls:RMButton">
                    <Grid x:Name="BtnInnerGrid" RenderTransformOrigin="0.5,0.5" BorderBrush="{ThemeResource RMWhiteSmoke}" BorderThickness="2" Background="{ThemeResource RMTranslucentBlackBrush}" CornerRadius="20" Padding="0">
                        <Grid.RenderTransform>
                            <CompositeTransform ScaleX="1" ScaleY="1" />
                        </Grid.RenderTransform>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="00:00:00.200000">
                                        <VisualTransition.GeneratedEasingFunction>
                                            <CubicEase EasingMode="EaseOut" />
                                        </VisualTransition.GeneratedEasingFunction>
                                    </VisualTransition>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <PointerUpThemeAnimation Storyboard.TargetName="BtnInnerGrid" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="PointerOver">
                                    <VisualState.Setters>
                                        <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.7" />
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <VisualState.Setters>
                                        <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.7" />
                                        <Setter Target="BtnInnerGrid.(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Value="0.9" />
                                        <Setter Target="BtnInnerGrid.(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Value="0.9" />
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <VisualState.Setters>
                                        <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.3" />
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid.RowDefinitions>
                            <RowDefinition x:Name="BtnGridTopRow" />
                            <RowDefinition x:Name="BtnGridBottomRow" />
                        </Grid.RowDefinitions>
                        <RelativePanel x:Name="TopRowRelativePanel" Grid.Column="0" Grid.Row="0">
                            <Viewbox x:Name="FontIconViewBox" Visibility="Collapsed">
                                <FontIcon x:Name="BtnFontIcon" FontFamily="Segoe MDL2 Assets" Glyph="&#xE700;" />
                            </Viewbox>
                            <Viewbox x:Name="ImageViewBox" Visibility="Visible">
                                <Image x:Name="BtnImage" Source="" />
                            </Viewbox>
                        </RelativePanel>
                        <RelativePanel x:Name="BottomRowRelativePanel" Grid.Column="0" Grid.Row="1">
                            <TextBlock x:Name="BtnTextBlock"  Text="Test fdgfxgsg sdg dsgdf sgdf" />
                        </RelativePanel>
                    </Grid>
                </ControlTemplate>

例如,我想要
BtnGridTopRow.Height=2*
按钮。宽度=150
BtnGridTopRow.Height=0和<代码>按钮。宽度=100用于另一种类型。目标是使每个按钮具有相同的CommonState,但具有不同的按钮样式,但继承了边框笔刷、背景等的主要样式

我在寻找最好的方法,因为我对XAML和UWP很陌生,但我在web(PHP、JS、CSS等)方面有15年的经验

希望它足够清晰

提前感谢,

UWP根据类按钮扩展中的ButtonType属性更改按钮样式的最佳方法是什么

更好的方法是控制不同的按钮类型样式。当
ButtonType
属性更改时,转到不同的VisualState

比如说

public enum XButtonType
 {
     TopState,
     HiddenTopState
 }
 public sealed class MyButton : Button
 {
     public MyButton()
     {
         this.DefaultStyleKey = typeof(MyButton);

     }
     public XButtonType ButtonType
     {
         get { return (XButtonType)GetValue(ButtonTypeProperty); }
         set { SetValue(ButtonTypeProperty, value); }
     }

     // Using a DependencyProperty as the backing store for ButtonType.  This enables animation, styling, binding, etc...
     public static readonly DependencyProperty ButtonTypeProperty =
         DependencyProperty.Register("ButtonType", typeof(XButtonType), typeof(MyButton), new PropertyMetadata(0, new PropertyChangedCallback(OnButtonTypeChange)));

     private static void OnButtonTypeChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
         var control = d as MyButton;
         switch ((XButtonType)e.NewValue)
         {
             case XButtonType.TopState:
                 VisualStateManager.GoToState(control, "TopState", true);
                 break;
             case XButtonType.HiddenTopState:
                 VisualStateManager.GoToState(control, "HiddenTopState", true);
                 break;
             default:
                 break;
         }
     }
 }
Xaml代码

<Style TargetType="local:MyButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyButton">
                <Grid
                    x:Name="BtnInnerGrid"
                    Padding="0"
                    BorderThickness="2"
                    CornerRadius="20"
                    RenderTransformOrigin="0.5,0.5">
                    <Grid.RenderTransform>
                        <CompositeTransform ScaleX="1" ScaleY="1" />
                    </Grid.RenderTransform>
                    <Grid.RowDefinitions>
                        <RowDefinition x:Name="BtnGridTopRow" />
                        <RowDefinition x:Name="BtnGridBottomRow" />
                    </Grid.RowDefinitions>
                    <RelativePanel
                        x:Name="TopRowRelativePanel"
                        Grid.Row="0"
                        Grid.Column="0">
                        <Viewbox x:Name="FontIconViewBox" Visibility="Collapsed">
                            <FontIcon
                                x:Name="BtnFontIcon"
                                FontFamily="Segoe MDL2 Assets"
                                Glyph="&#xE700;" />
                        </Viewbox>
                        <Viewbox x:Name="ImageViewBox" Visibility="Visible">
                            <Image x:Name="BtnImage" Source="" />
                        </Viewbox>
                    </RelativePanel>
                    <RelativePanel
                        x:Name="BottomRowRelativePanel"
                        Grid.Row="1"
                        Grid.Column="0">
                        <TextBlock x:Name="BtnTextBlock" Text="Test this is button content!" />
                    </RelativePanel>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="00:00:00.200000">
                                    <VisualTransition.GeneratedEasingFunction>
                                        <CubicEase EasingMode="EaseOut" />
                                    </VisualTransition.GeneratedEasingFunction>
                                </VisualTransition>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="BtnInnerGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <VisualState.Setters>
                                    <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.7" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <VisualState.Setters>
                                    <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.7" />
                                    <Setter Target="BtnInnerGrid.(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Value="0.9" />
                                    <Setter Target="BtnInnerGrid.(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Value="0.9" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <VisualState.Setters>
                                    <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.3" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ButtonTypeGroup">
                            <VisualState x:Name="TopState">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnGridTopRow" Storyboard.TargetProperty="Height">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="2*" />
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnInnerGrid" Storyboard.TargetProperty="Width">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="150" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                                <!--<VisualState.Setters>
                                    <Setter Property="Width" Value="100"/>
                                </VisualState.Setters>-->
                            </VisualState>
                            <VisualState x:Name="HiddenTopState">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnGridTopRow" Storyboard.TargetProperty="Height">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0" />
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnInnerGrid" Storyboard.TargetProperty="Width">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="100" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Grid>
    <local:MyButton  VerticalAlignment="Center" ButtonType="TopState"/>
</Grid>

用法

<Style TargetType="local:MyButton">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyButton">
                <Grid
                    x:Name="BtnInnerGrid"
                    Padding="0"
                    BorderThickness="2"
                    CornerRadius="20"
                    RenderTransformOrigin="0.5,0.5">
                    <Grid.RenderTransform>
                        <CompositeTransform ScaleX="1" ScaleY="1" />
                    </Grid.RenderTransform>
                    <Grid.RowDefinitions>
                        <RowDefinition x:Name="BtnGridTopRow" />
                        <RowDefinition x:Name="BtnGridBottomRow" />
                    </Grid.RowDefinitions>
                    <RelativePanel
                        x:Name="TopRowRelativePanel"
                        Grid.Row="0"
                        Grid.Column="0">
                        <Viewbox x:Name="FontIconViewBox" Visibility="Collapsed">
                            <FontIcon
                                x:Name="BtnFontIcon"
                                FontFamily="Segoe MDL2 Assets"
                                Glyph="&#xE700;" />
                        </Viewbox>
                        <Viewbox x:Name="ImageViewBox" Visibility="Visible">
                            <Image x:Name="BtnImage" Source="" />
                        </Viewbox>
                    </RelativePanel>
                    <RelativePanel
                        x:Name="BottomRowRelativePanel"
                        Grid.Row="1"
                        Grid.Column="0">
                        <TextBlock x:Name="BtnTextBlock" Text="Test this is button content!" />
                    </RelativePanel>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="00:00:00.200000">
                                    <VisualTransition.GeneratedEasingFunction>
                                        <CubicEase EasingMode="EaseOut" />
                                    </VisualTransition.GeneratedEasingFunction>
                                </VisualTransition>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="BtnInnerGrid" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <VisualState.Setters>
                                    <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.7" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <VisualState.Setters>
                                    <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.7" />
                                    <Setter Target="BtnInnerGrid.(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Value="0.9" />
                                    <Setter Target="BtnInnerGrid.(UIElement.RenderTransform).(CompositeTransform.ScaleY)" Value="0.9" />
                                </VisualState.Setters>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <VisualState.Setters>
                                    <Setter Target="BtnInnerGrid.(UIElement.Opacity)" Value="0.3" />
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ButtonTypeGroup">
                            <VisualState x:Name="TopState">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnGridTopRow" Storyboard.TargetProperty="Height">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="2*" />
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnInnerGrid" Storyboard.TargetProperty="Width">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="150" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                                <!--<VisualState.Setters>
                                    <Setter Property="Width" Value="100"/>
                                </VisualState.Setters>-->
                            </VisualState>
                            <VisualState x:Name="HiddenTopState">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnGridTopRow" Storyboard.TargetProperty="Height">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="0" />
                                    </ObjectAnimationUsingKeyFrames>

                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BtnInnerGrid" Storyboard.TargetProperty="Width">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="100" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Grid>
    <local:MyButton  VerticalAlignment="Center" ButtonType="TopState"/>
</Grid>


谢谢您的回答。这是我一直在寻找的,但当我运行应用程序时,VisualStateManager.GoToState(控件“HiddenTopState”,true);在OnButtonTypeChange方法中始终返回false我认为问题在于当ButtonType属性更改时样式没有加载完成,因此我们可以在控件加载事件中重新设置属性,如。