question

RogerSchlueter-7899 avatar image
0 Votes"
RogerSchlueter-7899 asked AdnanDedic edited

WPF Window Style Trigger is not Firing

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?

windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

HuiLiu-MSFT avatar image
1 Vote"
HuiLiu-MSFT answered HuiLiu-MSFT commented

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



33.png (3.5 KiB)
7.png (10.4 KiB)
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

That works because you created the public variable TypeID on the window. In my case, the DataContext of the window is a CollectionView and the current item of that CollectioinView is set when the user selects an item from a ComboBox which is synchronized with the current item. The TypeID is one property of the current item. Thus, I cannot use your approach.

0 Votes 0 ·

Hi,@ RogerSchlueter-7899 . Sorry for being late. Is there any update for your question? What is the code of your CollectionView, TypeID ,ComboBox and SelectedItem? Could you show me your relevant code to reproduce the problem and analyze the issue?

0 Votes 0 ·
AdnanDedic avatar image
0 Votes"
AdnanDedic answered AdnanDedic edited

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;
                 }
             }
         }
     }
 }




· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@AdnanDedic your statement that window width and height properties cannot be set in a data trigger is not correct. See the answer from HuiLiu-MSFT just above your post.

0 Votes 0 ·
AdnanDedic avatar image AdnanDedic RogerSchlueter-7899 ·

@RogerSchlueter-7899 they can be set, but only once. The height is set only when the style is applied, and when the value is not already set. In the mentioned post TypeID property is hard coded and always the same, etc. Your original DataTrigger is working correctly (try to set background color in a setter).

0 Votes 0 ·