如何在 MahApps.Metro 的 NumericUpDown 控件中交换 up/down 按钮?

How to swap up/down buttons in NumericUpDown control of MahApps.Metro?

我目前正在使用 MahApps.Metro NumericUpDown 控件更改图像堆栈中的帧。我从中得到的用户反馈是按钮感觉不对,直觉上左边的按钮会后退一帧,右边的按钮会向前移动。因此,我想交换按钮的顺序

我查看了控件的属性,但找不到任何可以让我更改按钮顺序的属性。

有没有办法做到这一点而不必滚动我自己的控件?

基本上我想从这个改变:

为此:

更新

最新的 MahApps 版本 (v2.x) 有新的 SwitchUpDownButtons 属性 可用于交换/切换按钮。

旧的 MahApps 版本

没有 属性 可以更改向上和向下按钮顺序的地方。但是您可以采用 MahApps.Metro 的 GitHub 存储库中提供的原始样式并更改模板。

<Style x:Key="CustomNumericUpDownStyle" TargetType="{x:Type Controls:NumericUpDown}" BasedOn="{StaticResource {x:Type Controls:NumericUpDown}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Controls:NumericUpDown}">
                <Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                    <Border x:Name="Base"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="{TemplateBinding Controls:ControlsHelper.CornerRadius}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    <Grid Margin="{TemplateBinding BorderThickness}">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition x:Name="PART_TextBoxColumn" Width="*" />
                            <ColumnDefinition x:Name="PART_ButtonsColumn" Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <TextBox x:Name="PART_TextBox"
                                    Grid.Column="0"
                                    MinWidth="20"
                                    MinHeight="0"
                                    Margin="0 0 -2 0"
                                    Padding="0"
                                    HorizontalAlignment="Stretch"
                                    HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                    Controls:ControlsHelper.DisabledVisualElementVisibility="Collapsed"
                                    Controls:TextBoxHelper.ButtonContent="{TemplateBinding Controls:TextBoxHelper.ButtonContent}"
                                    Controls:TextBoxHelper.ButtonContentTemplate="{TemplateBinding Controls:TextBoxHelper.ButtonContentTemplate}"
                                    Controls:TextBoxHelper.ButtonFontFamily="{TemplateBinding Controls:TextBoxHelper.ButtonFontFamily}"
                                    Controls:TextBoxHelper.ButtonFontSize="{TemplateBinding Controls:TextBoxHelper.ButtonFontSize}"
                                    Controls:TextBoxHelper.ButtonWidth="{TemplateBinding Controls:TextBoxHelper.ButtonWidth}"
                                    Controls:TextBoxHelper.ButtonsAlignment="{TemplateBinding ButtonsAlignment}"
                                    Controls:TextBoxHelper.ClearTextButton="{TemplateBinding Controls:TextBoxHelper.ClearTextButton}"
                                    Controls:TextBoxHelper.HasText="{TemplateBinding Controls:TextBoxHelper.HasText}"
                                    Controls:TextBoxHelper.SelectAllOnFocus="{TemplateBinding Controls:TextBoxHelper.SelectAllOnFocus}"
                                    Controls:TextBoxHelper.UseFloatingWatermark="{TemplateBinding Controls:TextBoxHelper.UseFloatingWatermark}"
                                    Controls:TextBoxHelper.Watermark="{TemplateBinding Controls:TextBoxHelper.Watermark}"
                                    Controls:TextBoxHelper.WatermarkAlignment="{TemplateBinding Controls:TextBoxHelper.WatermarkAlignment}"
                                    Controls:TextBoxHelper.WatermarkTrimming="{TemplateBinding Controls:TextBoxHelper.WatermarkTrimming}"
                                    Background="{x:Null}"
                                    BorderThickness="0"
                                    FocusVisualStyle="{x:Null}"
                                    Focusable="{TemplateBinding Focusable}"
                                    FontFamily="{TemplateBinding FontFamily}"
                                    FontSize="{TemplateBinding FontSize}"
                                    Foreground="{TemplateBinding Foreground}"
                                    HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                    IsReadOnly="{TemplateBinding IsReadOnly}"
                                    IsTabStop="{TemplateBinding IsTabStop}"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                    TabIndex="{TemplateBinding TabIndex}"
                                    VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" />
                        <StackPanel x:Name="PART_Buttons"
                                    Grid.Column="1"
                                    Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Padding, Converter={StaticResource ThicknessBindingConverter}, ConverterParameter={x:Static Converters:ThicknessSideType.Left}}"
                                    Orientation="Horizontal">
                            <!-- down is now the first button -->
                            <RepeatButton x:Name="PART_NumericDown"
                                            Width="{TemplateBinding UpDownButtonsWidth}"
                                            VerticalContentAlignment="Center"
                                            Delay="{TemplateBinding Delay}"
                                            Foreground="{TemplateBinding Foreground}"
                                            IsTabStop="False"
                                            Style="{DynamicResource ChromelessButtonStyle}">
                                <Path x:Name="PolygonDown"
                                        Width="14"
                                        Height="3"
                                        Data="F1 M 19,38L 57,38L 57,44L 19,44L 19,38 Z "
                                        Fill="{DynamicResource GrayBrush1}"
                                        Stretch="Fill" />
                            </RepeatButton>
                            <RepeatButton x:Name="PART_NumericUp"
                                            Width="{TemplateBinding UpDownButtonsWidth}"
                                            Delay="{TemplateBinding Delay}"
                                            Foreground="{TemplateBinding Foreground}"
                                            IsTabStop="False"
                                            Style="{DynamicResource ChromelessButtonStyle}">
                                <Path x:Name="PolygonUp"
                                        Width="14"
                                        Height="14"
                                        Data="F1 M 35,19L 41,19L 41,35L 57,35L 57,41L 41,41L 41,57L 35,57L 35,41L 19,41L 19,35L 35,35L 35,19 Z "
                                        Fill="{DynamicResource GrayBrush1}"
                                        Stretch="Fill" />
                            </RepeatButton>
                        </StackPanel>
                    </Grid>
                    <Border x:Name="DisabledVisualElement"
                            Background="{DynamicResource ControlsDisabledBrush}"
                            BorderBrush="{DynamicResource ControlsDisabledBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="{TemplateBinding Controls:ControlsHelper.CornerRadius}"
                            IsHitTestVisible="False"
                            Opacity="0"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                            Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Controls:ControlsHelper.DisabledVisualElementVisibility), Mode=OneWay}" />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="ButtonsAlignment" Value="Left">
                        <Setter TargetName="PART_Buttons" Property="Grid.Column" Value="0" />
                        <Setter TargetName="PART_Buttons" Property="Margin" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Padding, Converter={StaticResource ThicknessBindingConverter}, ConverterParameter={x:Static Converters:ThicknessSideType.Right}}" />
                        <Setter TargetName="PART_ButtonsColumn" Property="Width" Value="*" />
                        <Setter TargetName="PART_TextBox" Property="Grid.Column" Value="1" />
                        <Setter TargetName="PART_TextBox" Property="Margin" Value="-2 0 0 0" />
                        <Setter TargetName="PART_TextBox" Property="Margin" Value="-2 0 0 0" />
                        <Setter TargetName="PART_TextBoxColumn" Property="Width" Value="Auto" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="DisabledVisualElement" Property="Opacity" Value="0.6" />
                    </Trigger>
                    <Trigger Property="IsReadOnly" Value="True">
                        <Setter Property="InterceptArrowKeys" Value="False" />
                        <Setter Property="InterceptManualEnter" Value="False" />
                        <Setter Property="InterceptMouseWheel" Value="False" />
                        <Setter TargetName="PART_NumericDown" Property="IsEnabled" Value="False" />
                        <Setter TargetName="PART_NumericUp" Property="IsEnabled" Value="False" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsReadOnly" Value="False" />
                            <Condition Property="InterceptManualEnter" Value="False" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="PART_TextBox" Property="IsReadOnly" Value="True" />
                    </MultiTrigger>
                    <Trigger SourceName="PART_NumericUp" Property="IsMouseOver" Value="True">
                        <Setter TargetName="PART_NumericUp" Property="Background" Value="{DynamicResource GrayBrush8}" />
                        <Setter TargetName="PolygonUp" Property="Fill" Value="{DynamicResource AccentColorBrush}" />
                    </Trigger>
                    <Trigger SourceName="PART_NumericUp" Property="IsPressed" Value="True">
                        <Setter TargetName="PART_NumericUp" Property="Background" Value="{DynamicResource BlackBrush}" />
                        <Setter TargetName="PolygonUp" Property="Fill" Value="{DynamicResource WhiteBrush}" />
                    </Trigger>
                    <Trigger SourceName="PART_NumericDown" Property="IsMouseOver" Value="True">
                        <Setter TargetName="PART_NumericDown" Property="Background" Value="{DynamicResource GrayBrush8}" />
                        <Setter TargetName="PolygonDown" Property="Fill" Value="{DynamicResource AccentColorBrush}" />
                    </Trigger>
                    <Trigger SourceName="PART_NumericDown" Property="IsPressed" Value="True">
                        <Setter TargetName="PART_NumericDown" Property="Background" Value="{DynamicResource BlackBrush}" />
                        <Setter TargetName="PolygonDown" Property="Fill" Value="{DynamicResource WhiteBrush}" />
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Base" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Controls:ControlsHelper.MouseOverBorderBrush)}" />
                    </Trigger>
                    <Trigger SourceName="PART_TextBox" Property="IsFocused" Value="true">
                        <Setter TargetName="Base" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Controls:ControlsHelper.FocusBorderBrush)}" />
                    </Trigger>

                    <Trigger Property="HideUpDownButtons" Value="True">
                        <Setter TargetName="PART_Buttons" Property="Visibility" Value="Collapsed" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>