【问题标题】:Style of TextBox causes exception when loading control in other assembly在其他程序集中加载控件时,TextBox 的样式会导致异常
【发布时间】:2019-10-23 04:33:16
【问题描述】:

我为可重用控件创建了一个程序集(除其他外)。在此程序集中,有一个 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)));
}

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

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

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

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

【问题讨论】:

  • 为什么首先要在代码中应用样式?那是针对 MVVM...
  • 否则样式不会被应用。执行此操作的 MVVM 方式是什么?
  • 这取决于您想要做什么...如果您将在代码中创建的文本框添加到您的视图中,那么您已经在打破常规了。通常,您会使用项目控件并将其源绑定到可观察集合并告诉它如何显示给定数据。也许如果你在更大的范围内向我解释你在做什么,我可以提供帮助
  • 我创建了一个自定义文本框。 TextBox 在另一个项目中使用(它将与 XAML 一起添加)。 TextBox 提供了一个新属性。我的模型类绑定到这个属性,所以我很确定我在这里没有违反 MVVM 模式。
  • 如果你只是在代码中使用它,为什么不这样做: ? MVVM 意味着,除了将执行的代码与显示的视图分开之外,您正在更改代码中视图的设计/行为。除非我在这里遗漏了一些东西,否则这不是模式的确切用途......

标签: c# wpf resourcedictionary mergeddictionaries


【解决方案1】:

我做的和你想做的完全一样。创建一个FrameworkLibrary 并在每个customerSolution 上使用它。如果我定义 DefaultStyleKey 我使用未注释的过程。我不知道您是否在静态构造函数上获得了更好的性能。在您的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);
        //}
    }
}

测试应用程序(测试库)

App.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>

【讨论】:

  • 感谢您的回答。我已经完成了完全相同的步骤,我没有收到任何编译错误(或“卷曲”行),所以一切都找到了。当我启动应用程序时,它仍然崩溃......同样的异常。即使我添加了MyTextBoxStyle.xaml 而不是 Themes/Generic.xaml。我仔细检查了 Reflector,该文件位于程序集的 Resources 文件夹中。
【解决方案2】:

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

<ResourceDictionary Source="pack://application:,,,/WpfCustomControlLibrary1;component/Resources/MyTextBoxStyle.xaml" />

【讨论】:

  • 它适用于我的示例项目。看起来你有一些非标准的东西。确保您的 TextBoxStyle.xaml 位于正确的位置并标记为 Page
【解决方案3】:

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

<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>

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

【讨论】:

  • 哦,好吧,出于好奇,您的库使用的命名空间是什么?
【解决方案4】:

这是在您的新程序集中吗? xmlns:general="clr-namespace:com.testsoft.General" 如果该命名空间不存在,则可以将其从 xaml 中删除。

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

具体的方法我记不得了,所以上面是一个大范围的概括。

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

【讨论】:

  • 这会导致同样的异常。
  • 你真的用过吗?因为它不是对应该使用的代码的准确描述。
  • 请在此处检查答案的补充,我认为这可能是接下来需要检查的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
相关资源
最近更新 更多