WPF - How to access child properties in XAML not using ElementName?

cedric 61 Reputation points
2021-12-15T00:46:31.597+00:00

WPF - How to access child properties in XAML not using ElementName?

I know how to access parent properties to change child properties in XAML.
But need to figure out how to access child properties without ElementName.

This example consists of 1 Grid & 2 CheckBoxes.

LeftCheckBox Checked/Unchecked changes GridBackground via C# EventHandler.
Also, LeftCheckBox IsChecked changes it own Foreground by XAML.

In turn, GridBackground changes RightCheckBox IsChecked/Foreground by XAML.
RightCheckBox IsChecked has no effect.

Question:
How to replace the EventHandler with XAML Style Triggers not using ElementName?

157693-example.png

MainWindow.xaml

<Window x:Class="WpfApp1.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">  
  
	<Grid>  
  
		<Grid.ColumnDefinitions>  
			<ColumnDefinition Width="*" />  
			<ColumnDefinition Width="*" />  
		</Grid.ColumnDefinitions>  
		<Grid.RowDefinitions>  
			<RowDefinition Height="450" />  
		</Grid.RowDefinitions>  
  
		<Grid.Style>  
			<Style TargetType="Grid">  
				<Setter Property="VerticalAlignment" Value="Center" />  
			</Style>  
		</Grid.Style>  
  
		<Grid.Resources>  
			<Style TargetType="CheckBox">  
				<Setter Property="HorizontalAlignment" Value="Center" />  
				<Setter Property="VerticalAlignment" Value="Center" />  
			</Style>  
		</Grid.Resources>  
  
		<CheckBox Grid.Column="0" Content="LEFT CHECKBOX - CLICK ME">  
			<CheckBox.Style>  
				<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">  
					<EventSetter Event="Checked" Handler="LeftCheckBox_Toggled" />  
					<EventSetter Event="Unchecked"  Handler="LeftCheckBox_Toggled" />  
					<Style.Triggers>  
						<Trigger Property="IsChecked" Value="True">  
							<Setter Property="Foreground" Value="White" />  
						</Trigger>  
						<Trigger Property="IsChecked" Value="False">  
							<Setter Property="Foreground" Value="Black" />  
						</Trigger>  
					</Style.Triggers>  
				</Style>  
			</CheckBox.Style>  
		</CheckBox>  
  
		<CheckBox Grid.Column="1" Content="RIGHT CHECKBOX - PASSIVE">  
			<CheckBox.Style>  
				<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">  
					<Style.Triggers>  
						<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}, Path=Background}" Value="Black">  
							<Setter Property="IsChecked" Value="True" />  
							<Setter Property="Foreground" Value="White" />  
						</DataTrigger>  
						<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}, Path=Background}" Value="White">  
							<Setter Property="IsChecked" Value="False" />  
							<Setter Property="Foreground" Value="Black" />  
						</DataTrigger>  
					</Style.Triggers>  
				</Style>  
			</CheckBox.Style>  
		</CheckBox>  
  
	</Grid>  
</Window>  

MainWindiow.xaml.cs

using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Media;  
  
namespace WpfApp1  
{  
	public partial class MainWindow : Window  
	{  
		public MainWindow()  
		{  
			InitializeComponent();  
		}  
  
		private void LeftCheckBox_Toggled(object sender, RoutedEventArgs e)  
		{  
			CheckBox checkBox = (CheckBox)sender;  
			Grid grid = (Grid)VisualTreeHelper.GetParent(checkBox);  
			grid.Background = (bool)checkBox.IsChecked ? Brushes.Black : Brushes.White;  
		}  
	}  
}  
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,775 questions
0 comments No comments
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,321 Reputation points
    2021-12-15T04:07:48.59+00:00

    Hi Cedric,
    the best way is to use MVVM and Binding to properties in ViewModel. Try following demo:

    <Window x:Class="WpfApp1.Window090"  
            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"  
            xmlns:local="clr-namespace:WpfApp090"  
            mc:Ignorable="d"  
            Title="cedric-6087_211215" Height="450" Width="800">  
      
      <Window.DataContext>  
        <local:ViewModel/>  
      </Window.DataContext>  
      <Grid>  
      
        <Grid.ColumnDefinitions>  
          <ColumnDefinition Width="*" />  
          <ColumnDefinition Width="*" />  
        </Grid.ColumnDefinitions>  
        <Grid.RowDefinitions>  
          <RowDefinition Height="450" />  
        </Grid.RowDefinitions>  
      
        <Grid.Style>  
          <Style TargetType="Grid">  
            <Setter Property="VerticalAlignment" Value="Center" />  
            <Style.Triggers>  
              <DataTrigger Binding="{Binding LeftCheckBox}" Value="True">  
                <Setter Property="Background" Value="White" />  
              </DataTrigger>  
              <DataTrigger Binding="{Binding LeftCheckBox}" Value="True">  
                <Setter Property="Background" Value="Black" />  
              </DataTrigger>  
              <DataTrigger Binding="{Binding RightCheckBox}" Value="True">  
                <Setter Property="Background" Value="Yellow" />  
              </DataTrigger>  
            </Style.Triggers>  
          </Style>  
        </Grid.Style>  
      
        <Grid.Resources>  
          <Style TargetType="CheckBox">  
            <Setter Property="HorizontalAlignment" Value="Center" />  
            <Setter Property="VerticalAlignment" Value="Center" />  
          </Style>  
        </Grid.Resources>  
      
        <CheckBox Grid.Column="0" Content="LEFT CHECKBOX - CLICK ME" IsChecked="{Binding LeftCheckBox}">  
          <CheckBox.Style>  
            <Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">  
              <Style.Triggers>  
                <Trigger Property="IsChecked" Value="True">  
                  <Setter Property="Foreground" Value="White" />  
                </Trigger>  
                <Trigger Property="IsChecked" Value="False">  
                  <Setter Property="Foreground" Value="Black" />  
                </Trigger>  
              </Style.Triggers>  
            </Style>  
          </CheckBox.Style>  
        </CheckBox>  
      
        <CheckBox Grid.Column="1" Content="RIGHT CHECKBOX - PASSIVE" IsChecked="{Binding RightCheckBox}">  
          <CheckBox.Style>  
            <Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">  
              <Style.Triggers>  
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}, Path=Background}" Value="Black">  
                  <Setter Property="Foreground" Value="White" />  
                </DataTrigger>  
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}, Path=Background}" Value="White">  
                  <Setter Property="Foreground" Value="Black" />  
                </DataTrigger>  
              </Style.Triggers>  
            </Style>  
          </CheckBox.Style>  
        </CheckBox>  
      
      </Grid>  
      
    </Window>  
    

    ViewModel:

    namespace WpfApp090  
    {  
      public class ViewModel  
      {  
        public bool LeftCheckBox { get; set; }  
        public bool RightCheckBox { get; set; }  
      }  
    }  
    

    Result:

    157656-x.gif


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.