Why doesn't the Visual Studio 2022 designer show changes?

Oscallo 0 Reputation points
2023-06-18T15:50:03.08+00:00

I created a Custom Control from Window. Added a dependency property to it.

public static readonly DependencyProperty IsHideableProperty = DependencyProperty.Register(nameof(IsHideable), typeof(bool), typeof(ExtendedWindow),
new FrameworkPropertyMetadata(BooleanBoxes.TrueBox,new PropertyChangedCallback(OnIsHideableChanged)));

public bool IsHideable 
{
get{return (bool)GetValue(IsHideableProperty);}
set{SetValue(IsHideableProperty, BooleanBoxes.Box(value));}
}

The purpose of this dependency property is to hide and show the "PART_Hide_Button" using ControlTemplate.Triggers.

<ControlTemplate x:Key="DefaultExtendedWindowTemplate" TargetType="{x:Type ui:ExtendedWindow}">
        <ControlTemplate.Resources>
            <coverter:ToWhiteBackgroundBorderConventer x:Key="ToWhiteBackgroundBorderConventer"/>
        </ControlTemplate.Resources>
        <Grid>
            <Grid x:Name="PART_ExternalGrid" Background="{TemplateBinding Background}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="{Binding Source={StaticResource Window.HeaderBar.HeaderHeight}}"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid x:Name="PART_HeaderBar" Grid.Row="0" Panel.ZIndex="{Binding Source={StaticResource Window.HeaderBar.HeaderZIndex}}">
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Left" Margin="20,20,0,0">
                        <Image Source="{TemplateBinding Icon}" Height="{Binding Source={StaticResource Window.HeaderBar.HeaderIconHeight}}" Width="{Binding Source={StaticResource Window.HeaderBar.HeaderIconWidth}}"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Right" Margin="0,0,15,0">
                        <ui:RoundedButton x:Name="PART_Hide_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}" Command="{x:Static com:ExtendedSystemCommands.HideInTreyWindowCommand}" ToolTip="Hide" Content="{x:Static fil:WindowButtonFilling.HideButtonFilling}"/>
                        <ui:RoundedButton x:Name="PART_Minimize_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}" Command="{x:Static com:ExtendedSystemCommands.MinimizeWindowCommand}" ToolTip="Minimize" Content="{x:Static fil:WindowButtonFilling.MinimizeButtonFilling}"/>
                        <ui:RoundedButton x:Name="PART_MaximizeAndRestore_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}"/>
                        <ui:RoundedButton x:Name="PART_Close_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}" Command="{x:Static com:ExtendedSystemCommands.CloseWindowCommand}" ToolTip="Close" Content="{x:Static fil:WindowButtonFilling.CloseButtonFilling}"/>
                    </StackPanel>
                </Grid>
                <Grid Grid.RowSpan="2">
                    <AdornerDecorator>
                        <ContentPresenter
                                Content="{TemplateBinding Content}" 
                                ContentTemplate="{TemplateBinding ContentTemplate}" 
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </AdornerDecorator>
                    <ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="Collapsed" IsTabStop="False" />
                </Grid>
            </Grid>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="ui:ExtendedWindow.IsHideable" Value="False">
                <Setter TargetName="PART_Hide_Button" Property="Visibility" Value="Collapsed"/>
            </Trigger>
            
            <Trigger Property="ResizeMode" Value="CanResizeWithGrip">
                <Setter TargetName="WindowResizeGrip" Property="Visibility" Value="Visible" />
            </Trigger>

            <Trigger Property="WindowStyle" Value="ToolWindow">
                <Setter TargetName="PART_Minimize_Button" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Visibility" Value="Collapsed"/>
            </Trigger>

            <Trigger Property="WindowState" Value="Normal">
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Command" Value="{x:Static com:ExtendedSystemCommands.MaximizeWindowCommand}"/>
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Content" Value="{x:Static fil:WindowButtonFilling.MaximizeButtonFilling}"/>
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="ToolTip" Value="Maximize"/>

                <Setter TargetName="PART_ExternalGrid" Property="Margin" Value="0"/>
            </Trigger>

            <Trigger Property="WindowState" Value="Maximized">
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Command" Value="{x:Static com:ExtendedSystemCommands.RestoreWindowCommand}"/>
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Content" Value="{x:Static fil:WindowButtonFilling.RestoreButtonFilling}"/>
                <Setter TargetName="PART_MaximizeAndRestore_Button" Property="ToolTip" Value="Restore"/>

                <Setter TargetName="PART_ExternalGrid" Property="Margin" Value="7"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style TargetType="{x:Type ui:ExtendedWindow}">
        <Setter Property="RenderOptions.BitmapScalingMode" Value="HighQuality"/>
        <Setter Property="Background" Value="{DynamicResource Window.Static.Background}"/>
        <Setter Property="Foreground" Value="{DynamicResource Window.Static.Foreground}"/>
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="MinHeight" Value="90"/>
        <Setter Property="MinWidth" Value="260"/>
        <Setter Property="IsHideable" Value="True" />
        <Setter Property="Template" Value="{DynamicResource DefaultExtendedWindowTemplate}"/>
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CaptionHeight="{DynamicResource Window.HeaderBar.HeaderHeight}"
                              CornerRadius="0"
                              GlassFrameThickness="0"
                              NonClientFrameEdges="None"
                              ResizeBorderThickness="5"
                              UseAeroCaptionButtons="False" />
            </Setter.Value>
        </Setter>
    </Style>

The problem is that if I use this piece of code instead of the one above.

<Trigger Property="IsHideable" Value="False">
	<Setter TargetName="PART_Hide_Button" Property="Visibility" Value="Collapsed"/>
</Trigger>

Then I get the error "Property cannot have an undefined (null) value". Otherwise, there is no update in the designer. GIF attached.

Code.gif

As you can see, the left button does not disappear. Tell me where I'm wrong or what I'm not doing.

Developer technologies | Windows Presentation Foundation
Developer technologies | XAML
Developer technologies | C#
{count} votes

1 answer

Sort by: Most helpful
  1. Hui Liu-MSFT 48,681 Reputation points Microsoft External Staff
    2023-06-23T05:49:05.06+00:00

    Hi,@Oscallo.You could set DataTrigger in the style of PART_Hide_Button to trigger whether PART_Hide_Button is displayed, and delete the code that triggers the display part in ControlTemplate.Triggers

    You can update your code as follows.

    ExtendedWindow :

     public partial class ExtendedWindow : System.Windows.Window
        {
            /// <summary>
            ///     DependencyProperty свойства IsHideable.
            /// </summary>
            public static readonly DependencyProperty IsHideableProperty = DependencyProperty.Register(nameof(IsHideable), typeof(bool), typeof(ExtendedWindow),
                                   
                new FrameworkPropertyMetadata(BooleanBoxes.TrueBox, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
                );
         
          
            static ExtendedWindow()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(ExtendedWindow), new FrameworkPropertyMetadata(typeof(ExtendedWindow)));
            }
        }
    

    DefaultExtendedWindowTemplate:

     <ControlTemplate x:Key="DefaultExtendedWindowTemplate" TargetType="{x:Type ui:ExtendedWindow}">
            <Grid>
                <Grid x:Name="PART_ExternalGrid" Background="{TemplateBinding Background}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="{Binding Source={StaticResource Window.HeaderBar.HeaderHeight}}"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid x:Name="PART_HeaderBar" Grid.Row="0" Panel.ZIndex="{Binding Source={StaticResource Window.HeaderBar.HeaderZIndex}}">
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Left" Margin="20,20,0,0">
                            <Image Source="{TemplateBinding Icon}" Height="{Binding Source={StaticResource Window.HeaderBar.HeaderIconHeight}}" Width="{Binding Source={StaticResource Window.HeaderBar.HeaderIconWidth}}"/>
                        </StackPanel>
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Right" Margin="0,0,15,0">
                            <ui:RoundedButton x:Name="PART_Hide_Button" 
                                              Command="{x:Static com:ExtendedSystemCommands.HideInTreyWindowCommand}" 
                                              ToolTip="Hide" Content="{x:Static fil:WindowButtonFilling.HideButtonFilling}">
                                <ui:RoundedButton.Style>
                                    <Style TargetType="{x:Type ui:RoundedButton}">
                                        <Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
                                        <Setter Property="Foreground" Value="White"/>
                                        <Setter Property="Background" Value="#26FFFFFF"/>
                                        <Setter Property="BorderBrush" Value="Transparent"/>
                                        <Setter Property="Focusable" Value="False" />
                                        <Setter Property="Edge" Value="26"/>
                                        <Setter Property="CornerRadius" Value="20"/>
                                        <Setter Property="Margin" Value="0,0,10,0"/>
                                        <Setter Property="IsTabStop" Value="False"/>
                                        <Setter Property="Visibility" Value="Visible"/>
                                        <Style.Triggers>
                                           
                                            <DataTrigger Binding="{Binding IsHideable,RelativeSource={RelativeSource TemplatedParent}}" Value="false">
                                                <Setter Property="Visibility" Value="Collapsed"/>
                                            </DataTrigger>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter Property="Background" Value="#4CFFFFFF"/>
                                                <Setter Property="BorderBrush" Value="Transparent"/>
                                            </Trigger>
                                            <Trigger Property="IsPressed" Value="True">
                                                <Setter Property="Background" Value="#4C616161"/>
                                                <Setter Property="BorderBrush" Value="Transparent"/>
                                            </Trigger>
                                            <Trigger Property="IsEnabled" Value="False">
                                                <Setter Property="Background" Value="#7F252525"/>
                                                <Setter Property="BorderBrush" Value="Transparent"/>
                                            </Trigger>
                                        </Style.Triggers>
                                    </Style>
                                </ui:RoundedButton.Style>
                             
                                
                            </ui:RoundedButton>
                            <ui:RoundedButton x:Name="PART_Minimize_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}" Command="{x:Static com:ExtendedSystemCommands.MinimizeWindowCommand}" ToolTip="Minimize" Content="{x:Static fil:WindowButtonFilling.MinimizeButtonFilling}"/>
                            <ui:RoundedButton x:Name="PART_MaximizeAndRestore_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}"/>
                            <ui:RoundedButton x:Name="PART_Close_Button" Style="{DynamicResource DefaultWindowRightButtonStyle}" Command="{x:Static com:ExtendedSystemCommands.CloseWindowCommand}" ToolTip="Close" Content="{x:Static fil:WindowButtonFilling.CloseButtonFilling}"/>
                        </StackPanel>
                    </Grid>
                    <Grid Grid.RowSpan="2">
                        <AdornerDecorator>
                            <ContentPresenter
                                    Content="{TemplateBinding Content}" 
                                    ContentTemplate="{TemplateBinding ContentTemplate}" 
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </AdornerDecorator>
                        <ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Visibility="Collapsed" IsTabStop="False" />
                    </Grid>
                </Grid>
            </Grid>
            <ControlTemplate.Triggers>
               
                <Trigger Property="ResizeMode" Value="CanResizeWithGrip">
                    <Setter TargetName="WindowResizeGrip" Property="Visibility" Value="Visible" />
                </Trigger>
    
                <Trigger Property="WindowStyle" Value="ToolWindow">
                    <Setter TargetName="PART_Minimize_Button" Property="Visibility" Value="Collapsed"/>
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Visibility" Value="Collapsed"/>
                </Trigger>
    
                <Trigger Property="WindowState" Value="Normal">
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Command" Value="{x:Static com:ExtendedSystemCommands.MaximizeWindowCommand}"/>
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Content" Value="{x:Static fil:WindowButtonFilling.MaximizeButtonFilling}"/>
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="ToolTip" Value="Maximize"/>
    
                    <Setter TargetName="PART_ExternalGrid" Property="Margin" Value="0"/>
                </Trigger>
    
                <Trigger Property="WindowState" Value="Maximized">
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Command" Value="{x:Static com:ExtendedSystemCommands.RestoreWindowCommand}"/>
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="Content" Value="{x:Static fil:WindowButtonFilling.RestoreButtonFilling}"/>
                    <Setter TargetName="PART_MaximizeAndRestore_Button" Property="ToolTip" Value="Restore"/>
    
                    <Setter TargetName="PART_ExternalGrid" Property="Margin" Value="7"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    

    DashboardWindow :

      public partial class DashboardWindow : ExtendedWindow, INotifyPropertyChanged
        {
            public DashboardWindow()
            {
                InitializeComponent();
                DataContext = this;
            }
            private bool myvalue;
            public bool Value 
             {
            get { return myvalue; }
            set
            {
                if (myvalue != value)
                {
                        myvalue = value;
                    OnPropertyChanged(nameof(Value));
                }
            }
            }
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    DashboardWindow:

    <ui:ExtendedWindow x:Class="Temphouse.Windows.DashboardWindow"
            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:ui="clr-namespace:CoreLand.UI.CustomControls;assembly=CoreLand.UI"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Temphouse.Windows"
            d:Template="{DynamicResource DefaultExtendedWindowTemplate}" 
            mc:Ignorable="d" IsHideable="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
            Title="DashboardWindow" Height="450" Width="800" Icon="/Icon.ico">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition Width="179*"/>
            </Grid.ColumnDefinitions>
    
            <Separator Grid.Column="1" Style="{DynamicResource VerticalSeparatorStyle}"/>
            <CheckBox IsChecked="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="100" Height="100" Grid.Column="1"  Foreground="White" Content="value" Background="AliceBlue"/>
        </Grid>
    </ui:ExtendedWindow>
    
    
    

    The result:

    6


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


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.