2

我为可重用控件创建了一个程序集(除其他外)。在此程序集中,有一个 Themes/Generic.xaml 文件用于自定义控件样式。我想在单独的文件中为不同的控件实现不同的样式,所以我认为使用合并字典是个好主意。

我的 Generic/Themes.xaml 看起来像这样:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="../Resources/MyTextBoxStyle.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

文件 MyTextBoxStyle.xaml 如下所示:

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

    <Style TargetType="{x:Type general:MyTextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
        <Setter Property="IsReadOnly" Value="True" />
        <Setter Property="Foreground" Value="Black" />
        <Style.Triggers>
            <Trigger Property="IsReadOnly" Value="True">
                <Setter Property="Foreground" Value="Gray" />
            </Trigger>
        </Style.Triggers>
    </Style>
</ResourceDictionary>

我添加了一个静态构造函数,因此将应用样式:

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

在另一个程序集中使用此自定义 TextBox 时,应用程序崩溃并出现以下异常:

IOException: Die Ressource "resources/mytextboxstyle.xaml" kann nicht gefunden werden. (找不到资源)

但是,如果我不使用 MergedDictionary 方法并将所有样式 XAML 直接添加到 Generic/Themes.xaml 文件中,则一切正常。

我尝试将 MyTextBoxStyle.xaml 文件的 Build Action 更改为 Resource, Embedded Resource 但这没有帮助。如何使用 MergedDictionaries 并且仍然能够在其他程序集中使用样式化控件?

4

4 回答 4

1

我做的事情和你想做的完全一样。创建一个FrameworkLibrary并在每个customerSolution. 如果我定义 aDefaultStyleKey我使用未注释的过程。我不知道您是否在静态构造函数上获得了更好的性能。在你的CustomerApplication (Testbase)你只需要链接你Themes.xaml里面的App.xaml.

控件库 (WpfControlLibrary1)

using System.Windows;
using System.Windows.Controls;

namespace WpfControlLibrary1
{
    public class MyTextBox : TextBox
    {
        static MyTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(typeof(MyTextBox)));
        }

        //public MyTextBox()
        //{
        //    DefaultStyleKey = typeof(MyTextBox);
        //}
    }
}

测试应用程序(测试库)

应用程序.xaml

<Application x:Class="Testbase.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Testbase"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>
                 <ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/generic/Themes.xaml" />
             </ResourceDictionary.MergedDictionaries>
         </ResourceDictionary>
    </Application.Resources>
</Application>

在此处输入图像描述

于 2019-10-23T07:08:46.790 回答
0

使用程序集标识的资源的绝对路径(替换WpfCustomControlLibrary1为自定义控件库的程序集名称)。

<ResourceDictionary Source="pack://application:,,,/WpfCustomControlLibrary1;component/Resources/MyTextBoxStyle.xaml" />
于 2019-10-23T06:38:31.910 回答
0

这是在你的新装配中吗?xmlns:general="clr-namespace:com.testsoft.General" 如果该名称空间不存在,则可能将其从 xaml 中删除。

此外,如果它是一种资源,您可能必须通过类似的方式访问它<ResourceDictionary Source="pack://,,,Resources/MyTextBoxStyle.xaml" />

我不记得确切的方法,所以上面是一个广泛的概括。

您实际上是否将 WPFLibrary 作为资源包含在测试库项目中?因为如果没有,那就是你的问题,它没有将你的 wpf 项目中的 mytextbox 作为 dll 包括在内,因此它无法从项目中加载资源。

于 2019-10-23T05:35:29.413 回答
0

我通过将网址调整为此解决了这个问题:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlFramework.Wpf;component/Resources/MyPathTextBox.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

现在一切都按预期工作(正在应用样式并且没有抛出异常)。

于 2019-10-23T07:53:31.180 回答