【问题标题】:2 in 1 Button like Dual-Button2 合 1 按钮,如双按钮
【发布时间】:2025-12-26 12:35:16
【问题描述】:

我似乎无法创建一个看起来像这样的按钮(见图)。

我尝试将一个网格、2 个椭圆和 2 个文本块组合成看起来像的东西,但无法让两个不同的按钮看起来正确..

一般是一个按钮分成两半,然后转换成2个独立的按钮,S按钮和A按钮..

任何输入都会非常有帮助..

【问题讨论】:

  • 听起来你真正需要的只是两个紧挨着的按钮。按钮 1 是左半圆,按钮 2 是右半圆,然后只需设置按钮的内容或模板的样式即可。
  • 在发表评论之前,您是否阅读了任何答案?
  • 您没有将其中任何一个标记为您正在寻找的答案。如果其中有人回答了您的问题,请将其作为您选择的答案,否则请继续期待人们进来并对此发表评论,伙计。

标签: c# wpf xaml


【解决方案1】:

我可能已经设法创建了您正在寻找的东西。请注意,这需要进一步的工作,因为很多功能都没有实现。我所做的只是创建一个“双按钮”,它具有单独的可点击部分,并且看起来与您提供的一样。

您可以根据我的示例制定自己的样式和功能。

首先,它的外观:

现在,进入代码。我将它定义为一个 userControl,以便于管理和重用,而不会使 XAML 过于繁琐。

XAML:

<UserControl x:Class="WpfApplication2.DualButton"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfApplication2"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Button Click="Button_Click_1">
        <Button.Template>
            <ControlTemplate>
                <Grid>
                    <Path Fill="Lime" >
                        <Path.Data>
                            <PathGeometry>
                                <PathFigure StartPoint="150,0">
                                    <ArcSegment IsLargeArc="True"
                            Size="50, 50"
                            Point="150, 300"
                            SweepDirection="Counterclockwise" />
                                </PathFigure>
                            </PathGeometry>
                        </Path.Data>
                    </Path>
                    <TextBlock Margin="49,46,171,83" FontSize="150" TextAlignment="Center" HorizontalAlignment="Center" Foreground="White">S</TextBlock>
                </Grid>
            </ControlTemplate>
        </Button.Template>
    </Button>
    <Button Click="Button_Click_2">
        <Button.Template>
            <ControlTemplate>
                <Grid>
                    <Path Fill="Blue" >
                        <Path.Data>
                            <PathGeometry>
                                <PathFigure StartPoint="150,0">
                                    <ArcSegment IsLargeArc="True"
                            Size="50, 50"
                            Point="150, 300"
                            SweepDirection="Clockwise" />
                                </PathFigure>
                            </PathGeometry>
                        </Path.Data>
                    </Path>
                    <TextBlock Margin="162,47,41,84" FontSize="150" TextAlignment="Center" HorizontalAlignment="Center" Foreground="White" Width="97">A</TextBlock>
                </Grid>
            </ControlTemplate>
        </Button.Template>
    </Button>
</Grid>

那么,这里到底发生了什么?

首先,当然是布局网格。它包含两个buttons,它们的模板设置为PathGeometry 以创建一个椭圆。 (这里已经有一些需要改进的地方——我使用了固定值,所以button 不会真正可扩展。尝试将这些属性与grid 大小连接起来)

然后有一个textBlock 用于按钮半边的明显字母。再一次,我并没有太在意放置,我只是把它们拖到周围,这样它们看起来不错。你也可以自己解决这个问题(我希望:D)

现在,使用代码隐藏:

public partial class DualButton : UserControl
{
    public DualButton()
    {
        InitializeComponent();
    }

    public static readonly RoutedEvent ClickEvent =
EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(DualButton));

    public event RoutedEventHandler Click
    {
        add { AddHandler(ClickEvent, value); }
        remove { RemoveHandler(ClickEvent, value); }
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        System.Windows.MessageBox.Show("Left");
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        System.Windows.MessageBox.Show("Right");
    }
}

在这里,我们添加了一个RoutedEvent 以使我们的按钮真正可点击。我还添加了一些事件处理程序来检查一切是否按预期工作(确实如此!)

同样,这只是一个简单的示例,绝不是优化的。有很大的改进空间。我只是想把你推向正确的方向。

如果您还有其他问题,请随时提问。

【讨论】:

  • 看看我自己的答案..看看你是否喜欢它..我唯一不喜欢你的答案是你用于半圆形形状的路径..跨度>
  • 我也喜欢你的回答。至于路径,我不同意,因为通过正确的绑定,它可以产生任何所需的形状(不仅仅是椭圆)。您的 viewBox 想法也非常好,而且您的答案比我的更具 MVVM 模式,这很棒。老实说,我以为你不知道如何解决这个问题,所以我只是创建了一个快速的草稿示例,它是硬编码的,并没有太在意它的编写风格。我想我们的答案都有优点和缺点,但现在你的更发达:)
  • 我不是新手,即使我可以自己做,有时我也想看看别人会怎么做。我给你+1投票,因为你的回答还不错。。
  • 谢谢,非常感谢。祝你的新按钮好运^^
【解决方案2】:

在修改了 1 个网格、2 个椭圆和 2 个文本块之后,我让它工作了。 以及 2 个用于调整大小的 Viewbox。

Xaml:

<Window x:Class="Dual_Button.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Dual_Button"
        mc:Ignorable="d"
        Title="Dual Button" Height="260" Width="260">
    <Window.Resources>
        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
        <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
        <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
        <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
        <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        <SolidColorBrush x:Key="SubBack" Color="#FFD1FF00"/>
        <SolidColorBrush x:Key="AudioBack" Color="#FF00C5FF"/>
        <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                            <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsDefaulted" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                                <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid x:Name="grid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Ellipse x:Name="sub_Background" Height="{Binding ActualHeight, ElementName=grid, Mode=OneWay}" Width="{Binding ActualWidth, ElementName=grid, Mode=OneWay}" Fill="{DynamicResource SubBack}"/>
        <Button x:Name="btn_Sub" Background="{x:Null}" Foreground="White" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" VerticalAlignment="Center" Padding="0" BorderThickness="0" Click="btn_Sub_Click" Style="{DynamicResource ButtonStyle1}" MouseEnter="btn_Sub_MouseEnter" MouseLeave="btn_Sub_MouseLeave">
            <Viewbox Margin="25,10,10,25">
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="S"/>
            </Viewbox>
        </Button>
        <Ellipse x:Name="Audio_Background" Height="{Binding ActualHeight, ElementName=grid, Mode=OneWay}" Width="{Binding ActualWidth, ElementName=grid, Mode=OneWay}" Fill="{DynamicResource AudioBack}" Grid.Column="1" HorizontalAlignment="Right"/>
        <Button x:Name="btn_Audio" Background="{x:Null}" Foreground="White" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" VerticalAlignment="Center" Padding="0" BorderThickness="0" Grid.Column="1" Click="btn_Audio_Click" Style="{DynamicResource ButtonStyle1}" MouseEnter="btn_Audio_MouseEnter" MouseLeave="btn_Audio_MouseLeave">
            <Viewbox Margin="10,10,25,25">
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="A"/>
            </Viewbox>
        </Button>
    </Grid>
</Window>

后面的代码:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        void btn_Sub_MouseEnter(object sender, MouseEventArgs e)
        {
            try { sub_Background.Fill = Brushes.Red; } catch { }
        }
        void btn_Sub_MouseLeave(object sender, MouseEventArgs e)
        {
            try { sub_Background.Fill = (Brush)FindResource("SubBack"); } catch { }
        }
        void btn_Sub_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Subtitles");
        }

        void btn_Audio_MouseEnter(object sender, MouseEventArgs e)
        {
            try { Audio_Background.Fill = Brushes.Purple; } catch { }
        }
        void btn_Audio_MouseLeave(object sender, MouseEventArgs e)
        {
            try { Audio_Background.Fill = (Brush)FindResource("AudioBack"); } catch { }
        }
        void btn_Audio_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Audio");
        }
    }

这是我的结果:它是可扩展的..

当鼠标进入 S 按钮时,半圆将变为红色。 当鼠标进入A键时,半圆会变成紫色。

【讨论】: