如何在WPF样式中继承Button的行为?

3

我已经按照这里的说明重写了WPF默认的最大化和最小化按钮。但是,在我的情况下,我不想使用Image覆盖那些按钮的背景图片,而是想添加自己的模板。

因此,我创建了一个ResourceDictionary,为最大化/最小化/还原/关闭按钮应用样式。

问题在于我重写了模板。例如,请参见PART_MINIMIZE按钮:

 <Button x:Name="PART_MINIMIZE" 
      Width="30"
      Height="20"
      Margin="0,0,4,0"
      HorizontalAlignment="Center" 
      Template="{DynamicResource MinimizeButton}" 
      VerticalAlignment="Center" 
      DockPanel.Dock="Right">
  </Button>
DynamicResource调用的MinimizeButton建立了完整模板。问题出在当我点击按钮时。由于我覆盖了Template部分,默认情况下它没有被我定义的行为。但是我想保留默认的最大化/最小化/还原/关闭行为,而不覆盖它。所以...
如何在模板中表明继承按钮的行为?或者如何模拟它们?
谢谢!
3个回答

1
我认为你不应该覆盖模板,因为这样会失去控件的基本操作。你应该设置ContentTemplate而不是Template,因为ContentTemplate定义了按钮的外观,而不会阻碍其基本功能..
以下是您可以编辑按钮ContentTemplate的方法..
 <Button Grid.Column="3"  FontSize="22" FontWeight="Light" Opacity="0.5" BorderThickness="0" Margin="15,0,0,0" >
            <Button.ContentTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" >
                        <TextBlock Text="Search" />
                        <TextBlock Text="&#xE11A;" FontFamily="Segoe UI Symbol" FontSize="22" VerticalAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </Button.ContentTemplate>
        </Button>

如果您想在app.xaml中设置按钮的外观,只需像这样设置其DataTemplate即可。
        <DataTemplate x:Key="tempbtn">
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" Text="hellotxt" FontSize="30" />
                <TextBlock Grid.Row="1" Text="asdl;fjkladjglkad" FontSize="50" />
            </Grid>
        </DataTemplate>

在XAML中,您可以像这样在按钮上使用此数据模板:

<Button ContentTemplate="{StaticResource tempbtn}" Width="500" Height="200" />

我找不到如何在不改变“Template”的情况下更改“ContentTemplate”... 有任何想法吗? - Sonhja

1

Window 相关的操作应该放在一个特殊的类中,该类应该可以从 XAML 中访问,例如:

操作 Close

<Trigger Property="IsChecked" Value="True">
    <Setter Property="Controls:WindowBehaviours.Close" Value="True" />
</Trigger>

操作 Hide:

<Trigger Property="IsChecked" Value="True">
    <Setter Property="Controls:WindowBehaviours.Hide" Value="True" />
</Trigger>

这里使用了 ToggleButton,因为它拥有可以通过触发器访问的 IsChecked 属性。这些属性是附加属性。 WindowBehaviours 类的清单:
public static class WindowBehaviours
{
    // Close the Window
    public static void SetClose(DependencyObject target, bool value)
    {
        target.SetValue(CloseProperty, value);
    }

    public static readonly DependencyProperty CloseProperty =
                                              DependencyProperty.RegisterAttached("Close",
                                              typeof(bool),
                                              typeof(WindowBehaviours),
                                              new UIPropertyMetadata(false, OnClose));

    private static void OnClose(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue is bool && ((bool)e.NewValue))
        {
            Window window = GetWindow(sender);

            if (window != null)
            {
                window.Close();
            }
        }
    }

    // Hide the Window
    public static void SetHide(DependencyObject target, bool value)
    {
        target.SetValue(HideProperty, value);
    }

    public static readonly DependencyProperty HideProperty =
                                              DependencyProperty.RegisterAttached("Hide",
                                              typeof(bool),
                                              typeof(WindowBehaviours),
                                              new UIPropertyMetadata(false, OnHide));

    private static void OnHide(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue is bool && ((bool)e.NewValue))
        {
            Window window = GetWindow(sender);

            if (window != null)
            {
                window.WindowState = WindowState.Minimized;
            }
        }
    }

    // Full the Window
    public static void SetFull(DependencyObject target, bool value)
    {
        target.SetValue(FullProperty, value);
    }

    public static readonly DependencyProperty FullProperty =
                                              DependencyProperty.RegisterAttached("Full",
                                              typeof(bool),
                                              typeof(WindowBehaviours),
                                              new UIPropertyMetadata(false, OnFull));

    private static void OnFull(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue is bool && ((bool)e.NewValue))
        {
            Window window = GetWindow(sender);

            if (window != null)
            {
                window.WindowState = WindowState.Maximized;
            }
        }
    }

    // Set the Window in Normal
    public static void SetNormal(DependencyObject target, bool value)
    {
        target.SetValue(NormalProperty, value);
    }

    public static readonly DependencyProperty NormalProperty =
                                              DependencyProperty.RegisterAttached("Normal",
                                              typeof(bool),
                                              typeof(WindowBehaviours),
                                              new UIPropertyMetadata(false, OnNormal));

    private static void OnNormal(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue is bool && ((bool)e.NewValue))
        {
            Window window = GetWindow(sender);

            if (window != null)
            {
                window.WindowState = WindowState.Normal;
            }
        }
    }

    // Get the Window
    private static Window GetWindow(DependencyObject sender)
    {
        Window window = null;

        if (sender is Window)
        {
            window = (Window)sender;
        }

        if (window == null)
        {
            window = Window.GetWindow(sender);
        }

        return window;
    }
}

使用 WindowBehaviours 类与 ToggleButtons 的示例:

CloseButton

     <Style x:Key="ToggleButtonWindowClose" TargetType="{x:Type ToggleButton}">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="SnapsToDevicePixels" Value="True" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">                           
                       <Grid>
                            <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />

                            <Border x:Name="BorderClose" Background="Beige" BorderThickness="0" Width="22" Height="22" HorizontalAlignment="Right" Margin="0,6,8,0" VerticalAlignment="Top" Opacity="0" />
                            <Path x:Name="CloseWindow" SnapsToDevicePixels="True" ToolTip="Закрыть окно" Width="18" Height="17" Margin="0,0,10,0" HorizontalAlignment="Right" VerticalAlignment="Center" Stretch="Fill" Fill="#2D2D2D" Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z " />
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="CloseWindow" Property="Fill" Value="#C10000" />
                                <Setter TargetName="BorderClose" Property="Opacity" Value="1" />
                            </Trigger>

                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Controls:WindowBehaviours.Close" Value="True" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>    

"HideButton"。
    <Style x:Key="ButtonWindowHide" TargetType="{x:Type ToggleButton}">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="SnapsToDevicePixels" Value="True" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">
                        <Grid>
                            <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />

                            <Border x:Name="BorderHide" Background="Beige" BorderThickness="0" Width="22" Height="22" HorizontalAlignment="Right" Margin="0,6,32,0" VerticalAlignment="Top" Opacity="0" />
                            <Path x:Name="HideWindow" SnapsToDevicePixels="True" ToolTip="Скрыть окно" Width="14" Height="19" Margin="0,0,36,0" HorizontalAlignment="Right" VerticalAlignment="Center" Stretch="Fill" Fill="#2D2D2D" Data="F1 M 42,19.0002L 34,19.0002L 34,43.7502L 24,33.7502L 24,44.2502L 38,58.2502L 52,44.2502L 52,33.7502L 42,43.7502L 42,19.0002 Z " />
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="HideWindow" Property="Fill" Value="#0094FF" />
                                <Setter TargetName="BorderHide" Property="Opacity" Value="1" />
                            </Trigger>

                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Controls:WindowBehaviours.Hide" Value="True" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

FullScreenButton

         <Style x:Key="ButtonWindowFull" TargetType="{x:Type ToggleButton}">
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="SnapsToDevicePixels" Value="True" />

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToggleButton">
                        <Grid>
                            <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />

                            <Border x:Name="BorderFull" Background="Beige" BorderThickness="0" Width="22" Height="22" HorizontalAlignment="Right" Margin="0,6,58,0" VerticalAlignment="Top" Opacity="0" />
                            <Path x:Name="FullWindow" SnapsToDevicePixels="True" Width="19" Height="19" Margin="0,0,60,0" HorizontalAlignment="Right" VerticalAlignment="Center" Stretch="Fill" Fill="#2D2D2D" Data="F1 M 30.25,58L 18,58L 18,45.75L 22,41.75L 22,50.75L 30,42.75L 33.25,46L 25.25,54L 34.25,54L 30.25,58 Z M 58,45.75L 58,58L 45.75,58L 41.75,54L 50.75,54L 42.75,46L 46,42.75L 54,50.75L 54,41.75L 58,45.75 Z M 45.75,18L 58,18L 58,30.25L 54,34.25L 54,25.25L 46,33.25L 42.75,30L 50.75,22L 41.75,22L 45.75,18 Z M 18,30.25L 18,18L 30.25,18L 34.25,22L 25.25,22L 33.25,30L 30,33.25L 22,25.25L 22,34.25L 18,30.25 Z ">
                                <Path.ToolTip>
                                    <ToolTip x:Name="FullWindowToolTip" Content="Развернуть окно" />
                                </Path.ToolTip>
                            </Path>
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="FullWindow" Property="Fill" Value="#0094FF" />
                                <Setter TargetName="BorderFull" Property="Opacity" Value="1" />
                            </Trigger>

                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Controls:WindowBehaviours.Full" Value="True" />
                                <Setter TargetName="FullWindow" Property="Data" Value="F1 M 54.2499,34L 42,34L 42,21.7501L 45.9999,17.7501L 45.9999,26.7501L 53.9999,18.7501L 57.2499,22.0001L 49.2499,30.0001L 58.2499,30.0001L 54.2499,34 Z M 34,21.7501L 34,34L 21.75,34L 17.75,30.0001L 26.75,30.0001L 18.75,22.0001L 22,18.7501L 30,26.7501L 30,17.7501L 34,21.7501 Z M 21.75,42L 34,42L 34,54.25L 30,58.25L 30,49.25L 22,57.25L 18.75,54L 26.75,46L 17.75,46L 21.75,42 Z M 42,54.25L 42,42L 54.2499,42L 58.2499,46L 49.2499,46.0001L 57.2499,54L 53.9999,57.25L 45.9999,49.25L 45.9999,58.25L 42,54.25 Z " />
                                <Setter TargetName="FullWindowToolTip" Property="Content" Value="Hide in window" />
                            </Trigger>

                            <Trigger Property="IsChecked" Value="False">
                                <Setter Property="Controls:WindowBehaviours.Normal" Value="True" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

0

没有太多需要继承的东西。我建议您编写简单的处理程序并为按钮单击事件分配它们。处理程序可以如下:

    protected void MinimizeClick(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Minimized;
    }
    protected void MaximizeClick(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Maximized ;
    }

    protected void RestoreClick(object sender, RoutedEventArgs e)
    {
        WindowState = (WindowState == WindowState.Normal) ? WindowState.Maximized :     WindowState.Normal;
    }

    protected void CloseClick(object sender, RoutedEventArgs e)
    {
        Close();
    }

我无法访问那些按钮,因为它们是窗口预定义的。唯一的方法是覆盖它们,但我不能构建一个处理程序并将其分配... - Sonhja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接