窗口风格的多个内容呈现器打破了设计时间

问题描述 投票:0回答:1

我有自定义基窗口类,样式(和模板)被覆盖,如果模板仅包含 1 个 ContentPresenter(ContentSource=“Content”) - 它在设计器中显示良好,但如果我添加更多 ContentPresenter(将 ContentSource 设置为依赖属性)自定义窗口基类) - 它仍然可以编译并正常工作,但不再在设计器中显示此自定义样式,模板中出现错误,无法在 ControlTemplate 的 TargetType 字段中找到 CustomWindowBase 类型,这是可重现的示例:

自定义WindowBase.cs:

using System.Windows;

namespace WpfTest
{
    public class CustomWindowBase : Window
    {
        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(object), typeof(CustomWindowBase));
        public object Header
        {
            get => GetValue(HeaderProperty);
            set => SetValue(HeaderProperty, value);
        }

        public static readonly DependencyProperty FooterProperty = DependencyProperty.Register("Footer", typeof(object), typeof(CustomWindowBase));
        public object Footer
        {
            get => GetValue(FooterProperty);
            set => SetValue(FooterProperty, value);
        }

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

WindowStyle.xaml:

<ResourceDictionary xmlns:this="clr-namespace:WpfTest"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Style x:Key="CustomWindow" TargetType="this:CustomWindowBase">
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="Background" Value="#FF202020"/>
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CornerRadius="0" NonClientFrameEdges="None" GlassFrameThickness="0" ResizeBorderThickness="7" CaptionHeight="32"/>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type this:CustomWindowBase}">
                    <Grid Background="#FF202020">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="32"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="20"/>
                        </Grid.RowDefinitions>
                        <!--<ContentPresenter ContentSource="Header" ClipToBounds="True"/>-->
                        <ContentPresenter ContentSource="Content" Grid.Row="1" ClipToBounds="True"/>
                        <!--<ContentPresenter ContentSource="Footer" Grid.Row="2" ClipToBounds="True"/>-->
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

MainWindow.xaml.cs:

using System;
using System.Windows;
using System.Windows.Input;

namespace WpfTest
{
    public partial class MainWindow : CustomWindowBase
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

MainWindow.xaml:

<local:CustomWindowBase x:Class="WpfTest.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:WpfTest"
                        mc:Ignorable="d"
                        Title="MainWindow" Height="450" Width="800"
                        Style="{StaticResource CustomWindow}">
    <local:CustomWindowBase.Header>
        <TextBlock VerticalAlignment="Center" Text="SomeText" Foreground="White" FontSize="12"/>
    </local:CustomWindowBase.Header>
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="SomeText" Foreground="White" FontSize="40"/>
    <local:CustomWindowBase.Footer>
        <TextBlock VerticalAlignment="Center" Text="SomeText" Foreground="White" FontSize="12"/>
    </local:CustomWindowBase.Footer>
</local:CustomWindowBase>

应用程序.xaml:

<Application x:Class="WpfTest.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfTest"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="WindowStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

这在运行时和设计器中都显示良好,但是如果您在 WindowStyle.xaml 中取消注释两个 ContentPresenter - 它在设计器中不再工作,有什么想法如何解决这个问题吗?

.NET 7、Visual Studio 2022

c# wpf xaml window
1个回答
0
投票

当您覆盖

FrameworkElement.DefaultStyleKey
属性时,这意味着您有效地更改了默认
Style
所需的目标类型。
必须定义一个有效的默认值
Style

为了有效,这样的
Style
必须

  1. 是隐式的(没有显式的资源键)❌
  2. 位于 Generic.xaml 文件中 ❌
  3. 具有与
    Style.TargetType
    属性值的
    Type
    匹配的
    FrameworkElement.DefaultStyleKey
    值 ✔️

这意味着:

  1. 从默认
    x:Key
     中删除 
    Style
  2. 将默认的
    Style
    移至 Generic.xaml 文件(或将 WindowStyle.xaml 合并到 Generic.xaml 字典中)并
    • App.xaml 文件中删除合并的字典
    • CustomWindowBase.Style
      根元素中删除本地
      CustomWindowBase
      属性分配(在 MainWindow.xaml 中)
© www.soinside.com 2019 - 2024. All rights reserved.