【问题标题】:Display a StackPanel only if one of two options are selected in a radio button仅当在单选按钮中选择了两个选项之一时才显示 StackPanel
【发布时间】:2022-01-16 17:22:27
【问题描述】:

我有一个 WPF 应用程序,一页显示两个堆栈面板,其中包含单选按钮。我想要它,以便第二个堆栈面板的可见性取决于是否选择了某些单选按钮。

<Grid Background="#F8FBFD">
    <StackPanel x:Name="StackType" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,93,0,428">
        <materialDesign:Card Padding="32" Margin="16">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Type</TextBlock>
                <RadioButton Checked="NewMode_Checked" Content="New " x:Name="rbtnNew" GroupName="InstallType" IsChecked="{Binding newMode, Mode=TwoWay, Source={StaticResource modes}}"/>
                <RadioButton  Checked="UpgradeMode_Checked" Content="Update" x:Name="rbtnUpgrade" GroupName="InstallType" IsChecked="{Binding upgradeMode, Mode=TwoWay, Source={StaticResource modes}}" />
                <RadioButton  Checked="ChangeMode_Checked" Content="Change" x:Name="rbtnChange" GroupName="InstallType" IsChecked="{Binding changeMode, Mode=TwoWay, Source={StaticResource modes}}" />
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
    <StackPanel x:Name="StackMode" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" Visibility="Visible">
        <materialDesign:Card Padding="32" Margin="16" Width="204" Height="147">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Mode</TextBlock>
                <RadioButton Content="Default Settings" Name="rbtnDefaultMode" IsChecked="{Binding defaultMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="defaultSettings_Checked"/>
                <RadioButton Content="Custom Settings" Name="rbtnCustomMode" IsChecked="{Binding customMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="customSettings_Checked"/>
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
</Grid>

在此,我希望以某种方式使用它,以便在选择 rbtnNewrbtnUpgrade 时,只有这样 StackMode 面板才应该可见。如果选择了rbtnChange,则面板StackMode 应保持隐藏状态。

【问题讨论】:

  • 在您的视图模型中有多个布尔属性用于选择单个状态,这看起来很奇怪。显然mode 状态是newupgradechange,那么为什么不使用单个枚举类型的属性呢?然后,您可以使用适当的绑定转换器将第二个 StackPanel 的 Visibility 绑定到该枚举属性。您还可以在 StackOverflow 上找到如何通过一组 RadioButtons 设置枚举属性的解决方案。

标签: c# wpf xaml


【解决方案1】:

您可以使用DataTrigger 添加自定义样式:

  • StackMode 面板中删除Visibility="Visible"
  • 添加一个Setter,将StackPanel的默认值Visibility设置为Visible
  • 如果rbtnChangeIsChecked 值为true,则添加一个DataTrigger,将其值设置为Collapsed(或Hidden)。您可以在绑定中引用带有ElementName 的元素。
<Grid Background="#F8FBFD">
    <StackPanel x:Name="StackType" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,93,0,428">
        <materialDesign:Card Padding="32" Margin="16">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Type</TextBlock>
                <RadioButton Checked="NewMode_Checked" Content="New " x:Name="rbtnNew" GroupName="InstallType" IsChecked="{Binding newMode, Mode=TwoWay, Source={StaticResource modes}}"/>
                <RadioButton  Checked="UpgradeMode_Checked" Content="Update" x:Name="rbtnUpgrade" GroupName="InstallType" IsChecked="{Binding upgradeMode, Mode=TwoWay, Source={StaticResource modes}}" />
                <RadioButton  Checked="ChangeMode_Checked" Content="Change" x:Name="rbtnChange" GroupName="InstallType" IsChecked="{Binding changeMode, Mode=TwoWay, Source={StaticResource modes}}" />
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
    <StackPanel x:Name="StackMode" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal">
        <materialDesign:Card Padding="32" Margin="16" Width="204" Height="147">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Mode</TextBlock>
                <RadioButton Content="Default Settings" Name="rbtnDefaultMode" IsChecked="{Binding defaultMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="defaultSettings_Checked"/>
                <RadioButton Content="Custom Settings" Name="rbtnCustomMode" IsChecked="{Binding customMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="customSettings_Checked"/>
            </StackPanel>
        </materialDesign:Card>
        <StackPanel.Style>
           <Style TargetType="{x:Type StackPanel}">
              <Setter Property="Visibility" Value="Visible"/>
              <Style.Triggers>
                 <DataTrigger Binding="{Binding IsChecked, ElementName=rbtnChange}" Value="True">
                    <Setter Property="Visibility" Value="Collapsed"/>
                 </DataTrigger>
              </Style.Triggers>
           </Style>
        </StackPanel.Style>
    </StackPanel>
</Grid>

另一种选择是使用内置的BooleanToVisibilityConverter 转换器。

<Grid Background="#F8FBFD">
    <Grid.Resources>
       <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Grid.Resources>
    <StackPanel x:Name="StackType" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,93,0,428">
        <materialDesign:Card Padding="32" Margin="16">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Type</TextBlock>
                <RadioButton Checked="NewMode_Checked" Content="New " x:Name="rbtnNew" GroupName="InstallType" IsChecked="{Binding newMode, Mode=TwoWay, Source={StaticResource modes}}"/>
                <RadioButton  Checked="UpgradeMode_Checked" Content="Update" x:Name="rbtnUpgrade" GroupName="InstallType" IsChecked="{Binding upgradeMode, Mode=TwoWay, Source={StaticResource modes}}" />
                <RadioButton  Checked="ChangeMode_Checked" Content="Change" x:Name="rbtnChange" GroupName="InstallType" IsChecked="{Binding changeMode, Mode=TwoWay, Source={StaticResource modes}}" />
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
    <StackPanel x:Name="StackMode" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" Visibility="{Binding IsChecked, ElementName=rbtnChange, Converter={StaticResource BooleanToVisibilityConverter}}">
        <materialDesign:Card Padding="32" Margin="16" Width="204" Height="147">
            <StackPanel>
                <TextBlock HorizontalAlignment="Left" Style="{DynamicResource MaterialDesignTitleTextBlock}" >Installation Mode</TextBlock>
                <RadioButton Content="Default Settings" Name="rbtnDefaultMode" IsChecked="{Binding defaultMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="defaultSettings_Checked"/>
                <RadioButton Content="Custom Settings" Name="rbtnCustomMode" IsChecked="{Binding customMode, Source={StaticResource modes}, Mode=TwoWay}" Checked="customSettings_Checked"/>
            </StackPanel>
        </materialDesign:Card>
    </StackPanel>
</Grid>

更新您对初始状态应为Collapsed 的评论。您可以为rbtnChange RadioButtonIsChecked="False" 状态添加另一个DataTrigger

<Style TargetType="{x:Type StackPanel}">
   <Setter Property="Visibility" Value="Visible"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding IsChecked, ElementName=rbtnChange}" Value="False">
         <Setter Property="Visibility" Value="Collapsed"/>
      </DataTrigger>
      <DataTrigger Binding="{Binding IsChecked, ElementName=rbtnChange}" Value="True">
         <Setter Property="Visibility" Value="Visible"/>
      </DataTrigger>
   </Style.Triggers>
</Style>

当然,您也可以“反转”样式,将Collapsed 设置为默认值,并为每个其他RadioButtons 添加触发器以设置Visible,但更多按钮这不会很好地扩展。

【讨论】:

  • 这样做,如果我选择rbtnChange,上面的堆栈面板也会被隐藏。我试过这样做:`` `` 这似乎有效,但如何我可以为rbtnNewrbtnUpdate 做吗?
  • @PowershellScripter 哪个隐藏得好?选择rbtnChange 时,只有StackMode 将被隐藏,这也是您在问题中所要求的。 rbtnNewrbtnUpdate 应该怎么做呢?您的代码也是如此,但使用了转换器。
  • rbtnNewrbtnUpdate 应该使 StackMode 可见,rbtnChange 应该隐藏它。我已经尝试为所有三个单选按钮添加 DataTriggers,但我得到了相同的结果。如果我选择rbtnChange,两个堆栈面板都会隐藏。
  • @PowershellScripter Setter 设置值以防数据触发器未被触发。这意味着只有当rbtnChanges IsChecked 属性为True 时,Visibility 才会设置为Collapsed。在所有其他情况下,它将设置为Visible。不需要多个跳跳虎。我已经对此进行了测试,并且效果很好。您使用绑定转换器的示例也可以工作,但是它隐藏了materialDesign:Card.,而不是StackMode 面板,而不是StackPanel。如果这不起作用,则必须有另一个问题未在您的代码中显示。
  • @PowershellScripter 除此之外,仍然不清楚“两个堆栈面板”是哪个。您的意思是StackModeStackType 还是未命名的嵌套StackPanels 之一,或者您实际上是指Card?您的代码中是否还有其他面板未显示?哪个应该隐藏,哪个不应该隐藏?如前所述,当检查rbtnChange 时,只有StackMode(及其所有内容)将被隐藏。
猜你喜欢
  • 2019-08-12
  • 2016-09-28
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 2017-03-29
相关资源
最近更新 更多