WPF 切换面板可见性

7

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

在 xaml 中是否有一种很好的方法可以做到这一点,而不需要使用 codebehind 或 viewmodel?


面板 X 上的按钮应该使面板 X 变得可见,对吗? - Vlad
6个回答

3

实际上,这是可能的,但相当棘手。

我的示例不需要任何代码后台,实际上也不需要任何值转换器。

以下是代码:(现在是简化版本,感谢@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 的想法来自于SO上的其他问题

。在IT技术方面,这种方法可以实现一组按钮的单选功能。

@H.B.:您不能将切换按钮的样式设置为通用的:数据触发器每次都绑定到相反的按钮(分别是绿色按钮和红色按钮)。 - Vlad
天啊,将触发器移至单独的样式中,并基于控件模板样式进行设置。 - H.B.
@H.B.: 刚刚添加了已更正的版本:参数化使用DataContext。 - Vlad
@Vlad:我指的是我的版本(在提交编辑之前进行了测试)。 - H.B.
@H.B.:实际上,触发器不需要,因为我们正在使用ToggleButtons。我将完全删除它们。 - Vlad

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

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

它一直是内置的。WPF是在.NET 3.0中引入的,BooleanToVisibilityConverter也是如此。http://msdn.microsoft.com/en-us/library/system.windows.controls.booleantovisibilityconverter%28v=VS.85%29.aspx - Joe White

1
为什么不使用TabControl来实现这个?

好的建议,但对于这种情况没有用。 - Karsten
或许使用TabControl会很有用。将选项卡按钮移动到标题栏外面是可能的吗? - Karsten

0
一个IValueConverter的小技巧应该能解决问题。虽然它不是纯粹的XAML,但它不在代码后台并且可以重复使用。
我见过像将X可见性绑定到Y可见性,并添加转换器的东西:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
  return (Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}

-1

我不这么认为。你需要使用viewmodel或codebehind。使用带有DataTrigger的样式,并将可见性属性的值绑定到viewmodel中的一个属性,避免使用codebehind。


1
你低估了XAML。 - H.B.

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