WPF 切换面板可见性

发布于 2024-11-14 14:15:53 字数 104 浏览 1 评论 0原文

我有两个面板,但同时只能看到一个面板。我通过单击一个按钮(每个面板上一个)在它们之间进行切换。

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

I have two panels, only one should be visible at the same time. I change between them by clicking a button, one on each panel.

Is there a nice way to do this in xaml without codebehind or viewmodel?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

东京女 2024-11-21 14:15:53

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

我的示例可以在没有任何代码隐藏的情况下运行,实际上也没有任何值转换器。

这是代码:(现在是简化版本,感谢@HB的想法)

<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的想法是从一些其他问题所以

It's actually possible, however quite tricky.

My example works without any code-behind, actually without any value converters, too.

Here is the code: (now simplified version, thanks to @H.B. for ideas)

<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>

The idea of using ToggleButtons is stolen from some other question at SO

ぇ气 2024-11-21 14:15:53

使用选项卡控件的建议很好。我发现一些代码将 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

The suggestion with using a tabcontrol is good. I found some code which styles a TabControl to only show the TabItem content

<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
屋檐 2024-11-21 14:15:53

如果您使用 ToggleButtons,则可以将面板 1 的可见性绑定到按钮 2 的 IsChecked 状态,并将面板 2 的可见性绑定到按钮 1 的 IsChecked 状态。将它们设为 TwoWay 绑定并使用内置的 BooleanToVisibility 转换器。

If you used ToggleButtons, then you could bind the visibility of Panel 1 to the IsChecked state of Button 2, and the visibility of Panel 2 to the IsChecked state of Button 1. Make them TwoWay bindings and use the built-in BooleanToVisibility converter.

二智少女猫性小仙女 2024-11-21 14:15:53

为什么不使用 TabControl 呢?

Why not use the TabControl for this?

白云悠悠 2024-11-21 14:15:53

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

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

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

A little work around with a IValueConverter should do the trick. Sure it's not plain old XAML, but it's not in the codebehind and can be reuse.

I see something like binding X visibility to Y visibility and add a Converter to it :

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
  return (Visibility)value == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
星星的軌跡 2024-11-21 14:15:53

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

I don't think so. You would need to use viewmodel or codebehind. Use a Style with a DataTrigger and bind the value of the visibility property to a property in viewmodel, avoiding the use of codebehind.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文