Search code examples
wpfxamlcheckboxcomboboxdatatrigger

WPF deselect ComboBox with CheckBox - ComboBox with reset item


I am using DataTrigger to deselect ComboBox with CheckBox (Unchecked == deselected). What i Need is:

  1. when i select some item from ComboBox then CheckBox need to become Checked.
  2. When i uncheck CheckBox then ComboBox need to deselect.
  3. CheckBox cannot be checked if ComboBox is deselected (or if ComboBox is deselected after CheckBox is Checked ComboBox should be selected with first item)

Here is XAML (this is working version and need to be changed). Solution must be pure XAML (no C# code)!

 <CheckBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Margin="90,519,13,0" VerticalAlignment="Top" Height="21" Width="Auto">


<CheckBox.Style>
    <Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
        <Style.Resources>
            <Style TargetType="Path">
                <Setter Property="FlowDirection" Value="LeftToRight" />
            </Style>
            <Style TargetType="TextBlock">
                <Setter Property="FlowDirection" Value="LeftToRight" />
            </Style>
        </Style.Resources>

        <Setter Property="FlowDirection" Value="RightToLeft" />
        <!--<Setter Property="IsChecked" Value="True" />
                                                            <Style.Triggers>
                                                                <DataTrigger Binding="{Binding SelectedItem, ElementName=comboBoxEventDevice, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
                                                                    <Setter Property="IsChecked" Value="False" />
                                                                </DataTrigger>
                                                            </Style.Triggers>-->
    </Style>
</CheckBox.Style>
<ComboBox x:Name="comboBoxEventDevice" FlowDirection="LeftToRight" SelectionChanged="comboBoxEventDevice_SelectionChanged" Width="Auto">
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
            <Setter Property="SelectedIndex" Value="1" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="True">
                    <Setter Property="SelectedIndex" Value="0" />
                </DataTrigger>
                <!--<DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="False">
                                                                        <Setter Property="SelectedIndex" Value="1" />
                                                                    </DataTrigger>-->
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
</ComboBox>
</CheckBox>

UPDATE:

I try to not use nested controls (combobox inside checkbox) so i change XAML bu everything is same as before:

<CheckBox x:Name="checkBoxEventDevice" Margin="70,600,13,0" VerticalAlignment="Top" Height="21"/>
                                                <ComboBox x:Name="comboBoxEventDevice" Margin="90,519,10,0" VerticalAlignment="Top" SelectionChanged="comboBoxEventDevice_SelectionChanged">
                                                     <ComboBox.Style>
                                                        <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
                                                            <Setter Property="SelectedIndex" Value="1" />
                                                            <Style.Triggers>
                                                                <!--<DataTrigger Binding="{Binding Path=IsChecked, ElementName=checkBoxEventDevice}" Value="True">
                                                                    <Setter Property="SelectedIndex" Value="0" />
                                                                </DataTrigger>-->
                                                                <DataTrigger Binding="{Binding Path=IsChecked, ElementName=checkBoxEventDevice}" Value="false">
                                                                    <Setter Property="SelectedIndex" Value="-1" />
                                                                </DataTrigger>
                                                            </Style.Triggers>
                                                        </Style>
                                                    </ComboBox.Style>
                                                </ComboBox>

Problem is in <Setter Property="SelectedIndex" Value="1" /> line. If i remove it then ComboBox is deselected when datatrigger is off but if i keep it then when datatrigger is off combobox is set to second item. So i need some line where i can tell: do nothing, do not deselect combobox, keep current state.


Solution

  • I found solution and these features are satisfied :

    1. When i select some item from ComboBox then CheckBox need to become Checked.
    2. When i uncheck CheckBox then ComboBox need to deselect.
    3. If ComboBox is in deselected state, and when CheckBox is Checked ComboBox should be selected with first item (if items exist elsewhere CheckBox stays checked and ComboBox deselected).

    Here is XAML:

                                                    <CheckBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Margin="90,519,13,0" VerticalAlignment="Top" Height="21">
                                                        <CheckBox.Style>
                                                            <Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type CheckBox}}">
                                                                <Style.Resources>
                                                                    <Style TargetType="Path">
                                                                        <Setter Property="FlowDirection" Value="LeftToRight" />
                                                                    </Style>
                                                                    <Style TargetType="TextBlock">
                                                                        <Setter Property="FlowDirection" Value="LeftToRight" />
                                                                    </Style>
                                                                </Style.Resources>
                                                                <Setter Property="FlowDirection" Value="RightToLeft" />
                                                                <Setter Property="IsChecked" Value="True" />
                                                                <Style.Triggers>   
                                                                    <DataTrigger Binding="{Binding Path=SelectedIndex, ElementName=comboBoxEventDevice}" Value="-1">
                                                                        <Setter Property="IsChecked" Value="False" />
                                                                    </DataTrigger>
                                                                </Style.Triggers>
                                                            </Style>
                                                        </CheckBox.Style>
                                                        <ComboBox x:Name="comboBoxEventDevice" FlowDirection="LeftToRight" SelectionChanged="comboBoxEventDevice_SelectionChanged">
                                                            <ComboBox.Style>
                                                                <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
                                                                    <Setter Property="SelectedIndex" Value="0" />
                                                                    <Style.Triggers>
                                                                        <DataTrigger Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="False">
                                                                            <Setter Property="SelectedIndex" Value="-1" />
                                                                        </DataTrigger>
                                                                    </Style.Triggers>
                                                                </Style>
                                                            </ComboBox.Style>
                                                        </ComboBox>
                                                    </CheckBox>
    

    Now if someone need WPF nullable ComboBox all what need to do is to simple replace existing Combobox tag in its XAML code with XAML above and change x:Name and ElementName of ComboBox to original ComboBox in these lines:

    <DataTrigger Binding="{Binding Path=SelectedIndex, ElementName=comboBoxEventDevice}" Value="-1">
    
    <ComboBox x:Name="comboBoxEventDevice" FlowDirection="LeftToRight" SelectionChanged="comboBoxEventDevice_SelectionChanged">
    

    Also callback for SelectionChanged="comboBoxEventDevice_SelectionChanged" should be changed or removed depending do you need event handling or not. Margins of CheckBox need to be changed to your margins (and maybe you will need to add Width property but that depends on your project) in line:

    <CheckBox HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Margin="90,519,13,0" VerticalAlignment="Top" Height="21">