【问题标题】:WPF toggle panel visibilityWPF 切换面板可见性
【发布时间】:2024-04-12 13:15:02
【问题描述】:

我有两个面板,只能同时显示一个。我通过单击一个按钮在它们之间进行切换,每个面板上都有一个。

在没有代码隐藏或视图模型的情况下,有没有一种在 xaml 中执行此操作的好方法?

【问题讨论】:

  • 面板 X 上的按钮应该使面板 Xin可见,对吧?

标签: c# wpf xaml panel visibility


【解决方案1】:

这实际上是可能的,但非常棘手。

我的示例无需任何代码隐藏即可工作,实际上也无需任何值转换器。

这里是代码:(现在是简化版,感谢@H.B. 的想法)

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:sys="clr-namespace:System;assembly=mscorlib"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
    <Style x:Key="RBToggleButtonStyle" TargetType="RadioButton">
      <Setter Property="Template">
         <Setter.Value>
           <ControlTemplate>
              <ToggleButton
                 IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                 Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
           </ControlTemplate>
         </Setter.Value>
       </Setter>
       <Setter Property="Width" Value="150"/>
       <Setter Property="Height" Value="25"/>
       <Setter Property="HorizontalAlignment" Value="Right"/>
       <Setter Property="VerticalAlignment" Value="Bottom"/>
       <Setter Property="Margin" Value="15"/>
       <Setter Property="Content" Value="Hide"/>
    </Style>
    <Style x:Key="MyBorderStyle" TargetType="Border">
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsChecked}" Value="True">
          <Setter Property="Visibility" Value="Hidden"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Page.Resources>
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Border Background="Green" Grid.Column="0" Style="{StaticResource MyBorderStyle}" DataContext="{Binding ElementName=greenB}">
      <RadioButton x:Name="greenB" GroupName="x" Style="{StaticResource RBToggleButtonStyle}"/>
    </Border>
    <Border Background="Red" Grid.Column="1" Style="{StaticResource MyBorderStyle}" DataContext="{Binding ElementName=redB}">
      <RadioButton x:Name="redB" GroupName="x" Style="{StaticResource RBToggleButtonStyle}"/>
    </Border>
  </Grid>
</Page>

使用ToggleButtons的想法是从some other question at SO偷来的

【讨论】:

  • @H.B.:不能使切换按钮的样式通用:数据触发器每次都绑定到对面的按钮(分别为greenB和redB)
  • 哦,快,将触发器移动到单独的样式中,并将其基于仅控制模板的样式。
  • @H.B.:刚刚添加了更正的版本:使用 DataContext 参数化
  • @Vlad:我的意思是我的版本(我在提交编辑之前测试过)。
  • @H.B.:实际上,不需要触发器,因为我们使用的是 ToggleButtons。我会完全删除它们。
【解决方案2】:

使用 tabcontrol 的建议很好。我发现一些代码将 TabControl 设置为仅显示 TabItem 内容

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>
    <TabControl BorderThickness="0" Padding="0">
      <TabControl.Resources>
        <Style TargetType="TabItem">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="TabItem">
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </TabControl.Resources>
      <TabItem Header="Not shown">
        <Grid Background="Red"/>
      </TabItem>
      <TabItem>
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Tab 2

        </TextBlock>
      </TabItem>
    </TabControl>
  </Grid>
</P

【讨论】:

    【解决方案3】:

    如果您使用了 ToggleButtons,那么您可以将 Panel 1 的可见性绑定到 Button 2 的 IsChecked 状态,并将 Panel 2 的可见性绑定到 Button 1 的 IsChecked 状态。使它们成为双向绑定并使用内置的 BooleanToVisibility转换器。

    【讨论】:

    【解决方案4】:

    为什么不为此使用 TabControl?

    【讨论】:

    • 不错的建议,但对这种情况没有用
    • 或者使用 TabControl 可能会有用。是否可以将标签按钮移到标题之外?
    【解决方案5】:

    使用IValueConverter 进行一些处理应该可以解决问题。当然它不是普通的旧 XAML,但它不在代码隐藏中并且可以重用。

    我看到类似将 X 可见性绑定到 Y 可见性并向其添加转换器:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      return (Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
    }
    

    【讨论】:

      【解决方案6】:

      我不这么认为。您将需要使用视图模型或代码隐藏。使用带有 DataTrigger 的 Style 并将可见性属性的值绑定到 viewmodel 中的属性,避免使用代码隐藏。

      【讨论】:

      • 你低估了 XAML。