VS2022中的WPF自定义控件模板样式

ohfgkhjo  于 2023-08-07  发布在  其他
关注(0)|答案(1)|浏览(170)

我试图学习如何在WPF中通过资源字典控件模板进行自定义控件。我在Visual Studio 2022(.net 7 WPF)中设置了一个类和WPF测试应用程序项目,如下所示:


的数据
下面是控件“ButtonWheel”的XAML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
                    xmlns:PT="clr-namespace:PackagingTool.Controls">

    <Style TargetType="{x:Type PT:ButtonWheel}" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type PT:ButtonWheel}">
                    <Grid Background="Aqua" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Label Content="Test"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

字符串
C#控件:

using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;

namespace PackagingTool.Controls
{
    /// <summary>
    /// A control that represents as a single button, but opens up into a ring of buttons
    /// </summary>
    public class ButtonWheel : Button
    {
        static ButtonWheel() 
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonWheel), new FrameworkPropertyMetadata(typeof(ButtonWheel)));
        }
    }
}


我也有通用主题,这看起来是基于我在youtube上观看的视频所必需的:

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

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/PackagingTool;component/Themes/ButtonWheel.xaml" />
    </ResourceDictionary.MergedDictionaries>

</ResourceDictionary>


当我将这个自定义控件添加到测试应用程序时,如:

<Window x:Class="DemoApp.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:PT="clr-namespace:PackagingTool.Controls;assembly=PackagingTool"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <PT:ButtonWheel HorizontalAlignment="Center" VerticalAlignment="Center" Width="35" Height="35"/>
    </Grid>
</Window>


由于某些原因,它只是显示一个空框,而不是像控件模板中那样显示带有Test标签的Grid。它也没有给予任何错误,项目构建良好,并启动测试应用程序,所以我假设我可能错过了一些简单的东西,作为一个新手:),有人能告诉我哪里出错了吗?
我看了youtube视频:https://www.youtube.com/watch?v=KTNEz7DCRfohttps://www.youtube.com/watch?v=-YJqoZFAGPA&t=589s,我不认为我错过了什么。根据这些视频,我希望在添加控件时看到Test标签。

aiqt4smr

aiqt4smr1#

我觉得你少了一步。让我们把WPF中的资源处理想象成一棵树,其中每个 ResourceDictionary 都是一个叶子,它必须与 Backbone.js 链接才能工作。在我们的例子中, Backbone.js 是 App.xaml 文件,它提供了对所有应用程序文件的共享资源。如果MainWindow.xaml没有与您的自定义模板链接,它怎么能看到您的自定义模板呢?要解决这个问题,你有两种可能的方法:在MainWindow.xaml中声明 ResourceDictionary(如果您只想在该文件中使用它),或者在App.xaml文件中执行相同的操作(在所有应用程序文件中使用它)
解决方案1

<Window x:Class="DemoApp.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:PT="clr-namespace:PackagingTool.Controls;assembly=PackagingTool"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Window.Resources>
    <ResourceDictionary Source="pack://application:,,,/PackagingTool;component/Themes/ButtonWheel.xaml" />
</Window.Resources> 
<Grid>
    <PT:ButtonWheel HorizontalAlignment="Center" VerticalAlignment="Center" Width="35" Height="35"/>
</Grid>

字符串
解决方案2

<Application x:Class="DemoApp.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/PackagingTool;component/Themes/ButtonWheel.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>


P.S.我不确定资源本身的声明,因为你可以简单地用它的相对路径来声明它,例如。DemoApp/CustomControls/YourResource.xaml,但如果您看到的教程是这样说的,请按照其说明操作。
P.P.S.因为你听起来对WPF不是很有经验,我给予你一个技巧,检查一个ResourceDictionary是否正确链接,把光标放在它上面,然后按F12键(Visual Studio快捷键去定义),如果你打开文件,那么一切都正常。

相关问题