为什么在设计器时更改自定义依赖项属性 showCustomButon 值未在设计器窗口中更新

why change custom dependency property showcustombuton value not update in designer window in designer time

提问人:wpf 提问时间:6/28/2023 最后编辑:wpf 更新时间:6/28/2023 访问量:32

问:

都。为什么在设计器时更改自定义依赖项属性 showcustombuton 值未在设计器窗口中更新。

我尝试了很多,但没有结果。

我的期望:当 ShowCustomButton 的值为 False 时,设计器中的 Button 应该隐藏,当 ShowCustomButton 的值为 True 时,设计器中的 Button 应该显示。但是修改值后,按钮不会更改。 当我运行项目时,我的代码按预期工作。

我希望它在设计时在设计器窗口中按预期工作。

App.xaml:

  <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="\Themes\Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

Generic.xaml:

 <ControlTemplate  x:Key="d" TargetType="{x:Type local:CustomWin}">
        <Grid Background="{TemplateBinding Background}">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <StackPanel Grid.ColumnSpan="2">
                <TextBlock TextAlignment="Center"     Margin="0 10 0 0"   FontSize="22"   FontWeight="DemiBold"     Foreground="RoyalBlue"    Text="{TemplateBinding Title}"/>
            </StackPanel>
            <StackPanel Grid.Row="0" Grid.Column="1"     Orientation="Horizontal"   HorizontalAlignment="Stretch"     VerticalAlignment="Center"    Margin="0 10 15 0">
                <Button x:Name="PART_CustomButton"     Content="Custom Button"  Width="100"     Margin="0 0 10 0"     />
                <Button Content="+"     Width="25"  Height="22"    Margin="0 0 10 0"/>
                <Button Content="X"     Width="25"    Height="22" />
            </StackPanel>
            <ContentPresenter Grid.Row="1"/>
        </Grid>
    </ControlTemplate>

    <Style  TargetType="{x:Type local:CustomWin}" >
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="ResizeMode" Value="NoResize"/>
        <Setter Property="Background" Value="MintCream"/>
        <Setter Property="BorderBrush" Value="#0046E7"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="Template" Value="{StaticResource d}"/>
    </Style>

CustomWin 定制赢取 :

[DesignTimeVisible(true)]
public class CustomWin : Window
{
    public static readonly DependencyProperty ShowCustomButtonProperty =
        DependencyProperty.Register(
            "ShowCustomButton",
            typeof(bool),
            typeof(CustomWin),
            new PropertyMetadata(false, OnShowCustomButtonChanged)
        );

    [Category("Appearance")]
    public bool ShowCustomButton
    {
        get { return (bool)GetValue(ShowCustomButtonProperty); }
        set { SetValue(ShowCustomButtonProperty, value); }
    }

    private Button customButton;

    static CustomWin()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWin), new FrameworkPropertyMetadata(typeof(CustomWin)));
    }


    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        customButton = GetTemplateChild("PART_CustomButton") as Button;
        UpdateCustomButtonVisibility();
    }

    private static void OnShowCustomButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var window = (CustomWin)d;
        window.UpdateCustomButtonVisibility();
    }

    private void UpdateCustomButtonVisibility()
    {
        if (customButton != null)
        {
            customButton.Visibility = ShowCustomButton ? Visibility.Visible : Visibility.Collapsed;
        }
    }
}

MainWindow.xaml:

<local:CustomWin x:Class="WpfApp2.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:WpfApp2" 
        mc:Ignorable="d" Template="{StaticResource d }" ShowCustomButton="False"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

    </Grid>
</local:CustomWin>

   public partial class MainWindow : CustomWin
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

结果:

enter image description here

更新:

<local:BoolToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

 <Button x:Name="PART_CustomButton"     Content="Custom Button"  Width="100"     Margin="0 0 10 0"
                         Visibility="{Binding ShowCustomButton, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"/>

BoolToVisibilityConverter:

   public class BoolToVisibilityConverter : IValueConverter
    {
        private object GetVisibility(object value)
        {
            if (!(value is bool))
                return Visibility.Hidden;
            bool objValue = (bool)value;
            if (objValue)
            {
                return Visibility.Hidden;
            }
            else
            {
                return Visibility.Visible;
            }
        }
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return GetVisibility(value);
        }
        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }
    }

CustomWin 定制赢取 :

 [DesignTimeVisible(true)]
    public class CustomWin : Window
    {
        public static readonly DependencyProperty ShowCustomButtonProperty =
            DependencyProperty.Register(
                "ShowCustomButton",
                typeof(bool),
                typeof(CustomWin),
                new PropertyMetadata(false)
            );

        [Category("Appearance")]
        public bool ShowCustomButton
        {
            get { return (bool)GetValue(ShowCustomButtonProperty); }
            set { SetValue(ShowCustomButtonProperty, value); }
        }

    
        static CustomWin()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWin), new FrameworkPropertyMetadata(typeof(CustomWin)));
        }
}
C# WPF 窗口 自定义控件

评论

1赞 Clemens 6/28/2023
请注意,DependencyObject 不需要实现 INotifyPropertyChanged。依赖项属性已提供自己的更改通知机制。
0赞 wpf 6/28/2023
是的,这是我在设计时尝试让它工作的代码,现在我更新了。
1赞 Clemens 6/28/2023
可以将 ShowCustomButton 属性上的 Trigger 添加到 ControlTemplate,而不是访问 Template 中的元素(可能存在也可能不存在)的 PropertyChangedCallback。
1赞 Aaron 6/28/2023
据我所知,可见性仅在运行时更改。您可以在设计器本身中将属性“visible”更改为 false,该项仍将可见。为什么要在设计模式下隐藏某些内容?我真的没有看到它的用例。但是,可以将按钮包装在自定义控件中,并且仅在运行时加载它。这样它就会保持隐藏状态。
1赞 Clemens 6/28/2023
再注意一下,BoolToVisibilityConverter 中的逻辑已恢复。除此之外,您无需自己编写该转换器。框架中有一个。

答: 暂无答案