【问题标题】:How to create toggle button with label without duplicating code?如何在不重复代码的情况下创建带有标签的切换按钮?
【发布时间】:2020-01-15 02:35:35
【问题描述】:

我需要在切换按钮附近有一个文本,显示相对的开/关。

我通过简单地使用带有切换按钮和标签的堆栈面板来实现这一点,然后在后面的代码中我只需使用 Checked/Unchecked 事件来更改标签的内容。 问题是我有很多切换按钮,并且我的方法重复了代码(对于每个切换按钮,我都有一个标签和 2 个功能)。 有没有更有效的方法?

  <StackPanel Orientation="Horizontal">
 <ToggleButton Name="First" Checked="First_Checked" Unchecked="First_Unchecked"/>
     <Label Name="FirstLB" VerticalAlignment="Center"/>
       </StackPanel>

     <StackPanel Orientation="Horizontal">
    <ToggleButton Name="Second" Checked="Second_Checked" Unchecked="Second_Unchecked"/>
                        <Label Name="SecondLB" VerticalAlignment="Center"/>
       </StackPanel>


    private void First_Unchecked(object sender, RoutedEventArgs e)
    {
        FirstLB.Content = "Off";
    }

    private void Second_Unchecked(object sender, RoutedEventArgs e)
    {
        SecondLB.Content = "Off";

    }

    private void First_Checked(object sender, RoutedEventArgs e)
    {
        FirstLB.Content = "On";
    }

    private void Second_Checked(object sender, RoutedEventArgs e)
    {
        SecondLB.Content = "On";

    }

【问题讨论】:

  • 你能给我一些代码吗?如何访问每个切换按钮的标签?
  • 除此之外,您真的需要标签吗?为什么不设置 ToggleButton 自己的 Content?
  • 是的,我确实需要标签 - 文本应该出现在按钮旁边
  • 您考虑过使用复选框吗?
  • 不幸的是,我需要一个切换按钮。

标签: .net wpf xaml controls toggle


【解决方案1】:

好吧,听起来很简单,我创建了一本字典 字典 Btns;

添加了所有按钮和标签。

然后创建一个用于选中的函数和一个用于未选中的函数:

 private void Checked(object sender, RoutedEventArgs e)
        {
            Btns[(ToggleButton)sender].Content = "on;
        }

        private void UnChecked(object sender, RoutedEventArgs e)
        {
            Btns[(ToggleButton)sender].Content = "off";
        }

【讨论】:

    【解决方案2】:

    UserControl 的一种替代方法是在 ControlTemplate 中为 ToggleButton 嵌套 ToggleButton 和 TextBlock:

    <Window.Resources>
        <ControlTemplate TargetType="ToggleButton" x:Key="OnOffToggleButtonTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}}"/>
                <TextBlock x:Name="label" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Text="Off"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter TargetName="label" Property="Text" Value="On"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Window.Resources>
    

    会这样使用:

    <ToggleButton Template="{StaticResource OnOffToggleButtonTemplate}"
                  IsChecked="{Binding SomeViewModelProperty}" />
    

    【讨论】:

    • 这是一个很好的解决方案,但太乱了......我发布了我真正需要的东西
    • 好吧,我将其称为 reusable,而不是 messy。
    • 我会犹豫是否称之为“正确”,因为有一个嵌套的 ToggleButton,但它很简单。最好的方法可能是模板化 RadioButton,但这会涉及更多的 XAML。
    【解决方案3】:

    您可以创建一个带有IsChecked 属性的简单 UserControl,类似于 ToggleButton 类:

    <UserControl ...>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
            <TextBlock Grid.Column="1"
                       HorizontalAlignment="Center" VerticalAlignment="Center">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Setter Property="Text" Value="Off"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                         Value="True">
                                <Setter Property="Text" Value="On"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </Grid>
    </UserControl>
    

    后面有这段代码:

    public partial class OnOffButton : UserControl
    {
        public OnOffButton()
        {
            InitializeComponent();
        }
    
        public static readonly DependencyProperty IsCheckedProperty =
            ToggleButton.IsCheckedProperty.AddOwner(
                typeof(OnOffButton),
                new FrameworkPropertyMetadata(
                    null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    
        public bool? IsChecked
        {
            get { return (bool?)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }
    }
    

    你可以像 ToggleButton 一样使用它:

    <local:OnOffButton IsChecked="{Binding SomeViewModelProperty}"/>
    

    【讨论】:

      猜你喜欢
      • 2014-10-21
      • 1970-01-01
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多