Home > Net >  Collapse CheckBox if ComboBox has no element selected
Collapse CheckBox if ComboBox has no element selected

Time:12-18

I'm trying to collapse a CheckBox through Visibility if the selected item of a ComboBox is null or empty. The source is a list of objects having two string properties: Code and Name.

I'm using a trigger binded to the ComboBox text.

<ComboBox x:Name="VideoSub" SelectedItem="{Binding SubSelection, Mode=TwoWay}"
          ItemsSource="{Binding Path=SubsSource}"
          IsEnabled="{Binding HasItems, RelativeSource={RelativeSource Self}}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Name}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
<CheckBox Width="80" IsEnabled="{Binding ElementName=VideoSub, Path=IsEnabled}"
          HorizontalAlignment="Right" Margin="0,10,0,0">
    <CheckBox.Style>
        <Style TargetType="{x:Type CheckBox}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Text.Length, ElementName=VideoSub, UpdateSourceTrigger=PropertyChanged}" Value="0">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

CodePudding user response:

It is more directly to use event SelectionChanged to control whether components are displayed.

I wrote some demo code, hope it helps:

MainWindow.xaml

<Window x:Class="TestWpfApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">        
    <StackPanel>
        <ComboBox Name="MyComboBox" SelectionChanged="ComboBox_SelectionChanged">
            <ComboBoxItem Content="Code"></ComboBoxItem>  
            <ComboBoxItem Content="Name"></ComboBoxItem>  
        </ComboBox>
        <CheckBox Name="MyCheckBox" Visibility="Collapsed" />
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace TestWpfApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.MyComboBox.SelectedItem == null)
            {
                this.MyCheckBox.Visibility = Visibility.Collapsed;
            }
            else
            {
                this.MyCheckBox.Visibility = Visibility.Visible;
            }
        }
    }
}

Furthermore, sometimes it's easier to use procedure (such as functions/methods) than definition (such as triggers etc) in programming :)

CodePudding user response:

If you are using a DataTemplate, you should not trigger on elements inside it, but its data. If you want to hide the CheckBox when the SelectedItem is null, use the x:Null markup extension for comparison.

<DataTrigger Binding="{Binding SelectedItem, ElementName=VideoSub}" Value="{x:Null}">
   <Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>

As you bind Name to the TextBlock, you can add a DataTrigger to your style, that compares it to the static empty string. There is no need to reference the TextBlock itself.

<DataTrigger Binding="{Binding SelectedItem.Name, ElementName=VideoSub}" Value="{x:Static system:String.Empty}">
   <Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>

Note that you have to add an XML namespace for the String type.

  • .NET Core: xmlns:system="clr-namespace:System;assembly=System.Runtime"
  • .NET Framework: xmlns:system="clr-namespace:System;assembly=mscorlib"

Here the complete style that checks for null and emptyness.

<Style TargetType="{x:Type CheckBox}">
   <Style.Triggers>
      <DataTrigger Binding="{Binding SelectedItem, ElementName=VideoSub}" Value="{x:Null}">
         <Setter Property="Visibility" Value="Collapsed" />
      </DataTrigger>
      <DataTrigger Binding="{Binding SelectedItem.(local:PersonModel.Name), ElementName=VideoSub}" Value="{x:Static system:String.Empty}">
         <Setter Property="Visibility" Value="Collapsed" />
      </DataTrigger>
   </Style.Triggers>
</Style>

By the way, you probably do not need a DataTemplate at all, if you just want to display a property as text in the ComboBox. Set the DisplayMemberPath instead.

<ComboBox x:Name="VideoSub" SelectedItem="{Binding SubSelection, Mode=TwoWay}"
          ItemsSource="{Binding Path=SubsSource}"
          IsEnabled="{Binding HasItems, RelativeSource={RelativeSource Self}}"
          DisplayMemberPath="Name"/>

CodePudding user response:

Just bind to SelectedItem:

<CheckBox Width="80" IsEnabled="{Binding ElementName=VideoSub, Path=IsEnabled}"
          HorizontalAlignment="Right" Margin="0,10,0,0">
    <CheckBox.Style>
        <Style TargetType="{x:Type CheckBox}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SelectedItem, ElementName=VideoSub}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

An object itself "having two string properties: Code and Name" cannot be "empty".

There either is an item selected or there isn't.

  • Related