WPF Window Style Trigger is not Firing

RogerSchlueter-7899 1,446 Reputation points
2021-07-26T17:56:23.273+00:00

I have the following in my XAML Window:

<Window.Style>
        <Style
            TargetType="Window">
            <Setter Property="Height" Value="160" />
            <Style.Triggers>
                <DataTrigger
                    Binding="{Binding Path=/TypeID}" Value="14">
                    <Setter Property="Height" Value="290" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Style>

Seems straightforward, yet when TypeID = 14 the Height property of the window does not change. Can you see why?

Developer technologies Windows Presentation Foundation
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 48,676 Reputation points Microsoft External Staff
    2021-07-27T03:07:48.043+00:00

    You could try to refer to the following code. And make sure not to set the Width and Height properties of the window in XAML, because local values take precedence over the values set by the style setter.
    The code of xaml is as follows:

    <Window x:Class="StyleTrigger.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"  
            xmlns:local="clr-namespace:StyleTrigger"  
            mc:Ignorable="d"  
            Title="MainWindow"  Name="window">  
        <Window.Style>  
            <Style TargetType="Window">  
                <Style.Triggers>  
                    <DataTrigger Binding="{Binding Path=TypeID ,ElementName=window}" Value="2">  
                        <Setter Property="Height" Value="300"/>  
                        <Setter Property="Width" Value="100"/>  
                    </DataTrigger>  
                </Style.Triggers>  
            </Style>  
        </Window.Style>  
        <Grid>  
            <TextBlock Text="test" FontSize="20" FontWeight="Bold"/>  
        </Grid>  
    </Window>  
    

    The code of xaml.cs is as follows:

     public partial class MainWindow : Window  
      {  
        public MainWindow()  
        {  
          InitializeComponent();  
        }  
        public int TypeID { get; set; } = 2;    
        //public int TypeID { get; set; } = 10;   
    
      }           
    

    The result is shown in the figure:
    Result graph when TypeID = 2:
    118028-33.png
    Result graph when TypeID = 10:
    118089-7.png

    1 person found this answer helpful.

  2. Adnan Dedic 406 Reputation points
    2021-08-08T03:24:29.013+00:00

    Hi,
    Window width and height properties cannot be set in a data trigger.
    You can achieve the desired result using different solutions (depending on what you want to create and other window properties):

    1) If the window is not resizable, then you can set "MinHeight" and "MaxHeight" properties in the setter.
    2) If you want to use events, then you can subscribe to CollectionView.CurrentChanged event, check TypeID and set height in the code behind.
    3) etc.

    I think that best solution will be to use attached property and sync window height with it. You can use it in any window you want, in different data triggers, on the same way like you initially wanted to use Height property. It will also respect other window properties like MaxWidth, MinWidth, etc., and it will not require any workarounds like default/design time window size, etc.

    Here is the example based on your xaml and description. The relevant parts are different property name in the setter and window helper class.

    XAML:

    <Window x:Class="WpfApp6.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"
            xmlns:local="clr-namespace:WpfApp6"
            mc:Ignorable="d" Width="300" Height="300" Title="MainWindow">
        <Window.Style>
            <Style TargetType="{x:Type local:MainWindow}">
                <Setter Property="local:WindowHelper.DesiredHeight" Value="160"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=/TypeID}" Value="14">
                        <Setter Property="local:WindowHelper.DesiredHeight" Value="290"/>
                        <Setter Property="Background" Value="Green"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Window.Style>
        <Grid>
            <ComboBox ItemsSource="{Binding}" Height="40">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding TypeID}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
        </Grid>
    </Window>
    

    CS:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Data;
    
    namespace WpfApp6
    {
        public partial class MainWindow : Window
        {
            public MainWindow() {
                InitializeComponent();
                SetDataContext();
            }
            private void SetDataContext() {
                var collection = new List<Item>();
                for (int i = 0; i < 15; i++) {
                    collection.Add(new Item(i));
                }
                var collectionView = new CollectionView(collection);
                DataContext = collectionView;
            }
        }
        public class Item
        {
            public Item(int typeID) {
                TypeID = typeID;
            }
            public int TypeID { get; set; }
        }
        public static class WindowHelper
        {
            public static readonly DependencyProperty DesiredHeightProperty =
                DependencyProperty.RegisterAttached(
                    "DesiredHeight",
                    typeof(double),
                    typeof(WindowHelper),
                    new FrameworkPropertyMetadata(double.NaN, OnDesiredPropertyChanged));
    
            public static double GetDesiredHeight(Window window) {
                var desiredHeight = window.GetValue(DesiredHeightProperty);
                return desiredHeight is double ? (double)desiredHeight : double.NaN;
            }
            public static void SetDesiredHeight(Window window, double value) {
                window.SetValue(DesiredHeightProperty, value);
            }
            private static void OnDesiredPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
                if (d is Window window) {
                    var newValue = e.NewValue;
                    if (newValue is double) {
                        window.Height = (double)newValue;
                    }
                }
            }
        }
    }
    

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.