gpt4 book ai didi

WPF pack :/[assemblyName];component/. .. vs pack ://application:, ,,/[assemblyName];component/...?

转载 作者:行者123 更新时间:2023-12-04 21:47:16 45 4
gpt4 key购买 nike

在我正在处理的 WPF 应用程序中尝试使用合并的 ResourceDictionaries 解决问题时,我遇到了这个奇怪的问题。

我在外部 DLL(“通用”)中定义了自定义控件(TextButton、MenuButton)和资源(颜色、画笔、控件样式和自定义控件模板)。在另一个库中,我有一个使用这些样式的用户控件(“pluginA”)。

只要我使用的是标准 WPF 控件(TextBlock、Button、Grid 等),我就可以毫无问题地应用“通用”dll 中的样式。设计师会挑选样式并正确应用它。

如果我将其中一个自定义控件 (TextButton) 放入“pluginA”中的用户控件中 - 设计人员会找到自定义控件,但无法将样式的类型解析为被应用(类型引用找不到名为“{clr-namespace:Common}TextButton”的类型)。

我的用户控件中的 xmlns 声明如下所示:

<UserControl x:Class="PluginA.Views.LeftBarView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:core="clr-namespace:Common.Core;assembly=Common"
xmlns:common="clr-namespace:Common;assembly=Common"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<core:SharedResourceDictionary Source="/Common;component/Resources/DefaultTheme/DefaultTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>

使用此定义,设计器不应用任何样式 - 但它在运行时起作用。很好,但不是很有帮助,因为我不想运行应用程序来查看小的调整是否生效。

所以我尝试了这个:

<core:SharedResourceDictionary Source="pack://application:,,,/Common;component/Resources/DefaultTheme/DefaultTheme.xaml" />

但这并没有改变任何东西(设计师仍然找不到资源)。在更改代码的过程中,我得到了这个:

<core:SharedResourceDictionary Source="pack:/Common;component/Resources/DefaultTheme/DefaultTheme.xaml" />

现在设计师很高兴并且可以找到资源 - 运行时很高兴并显示资源,但我找不到任何关于这是有效 PACK URI 的描述......任何人都可以解释为什么这会起作用吗?

最佳答案

pack:/Common;component/Resources/DefaultTheme/DefaultTheme.xaml

这在技术上是一个有效的 URI,但它不是一个有效的 pack网址。按照pack的规则解析格式将产生:

包 URI: <empty>
零件 URI:/Common;component/Resources/DefaultTheme/DefaultTheme.xaml

实际上,您通过附加 pack: 从部分 URI 中创建了一个绝对 URI。方案。但是,如果没有格式良好的包组件,结果将不是有效的 pack。网址。而且,有趣的是,Uri类实际上不会将原始字符串解析为绝对 URI;它被错误地解析为相对 URI,这是它在分配给 ResourceDictionary.Source 时起作用的部分原因.让我们看一下属性 setter :

public Uri Source
{
get { return _source; }
set
{
// ...
_source = value;

Clear();

Uri uri = BindUriHelper.GetResolvedUri(_baseUri, _source);
WebRequest request = WpfWebRequestHelper.CreateRequest(uri);
// ...
}

关键在于BindUriHelper.GetResolvedUri(_baseUri, _source) .那里的逻辑与 pack 的大部分内容不同WPF 中的 URI 处理,看到 _source不是绝对 URI(至少根据损坏的 Uri 类),因此它尝试将它与解析的基本 URI 组合,我们假定它是 pack://application:,,,/ . URI 通过 new Uri(Uri baseUri, Uri relativeUri) 组合, 之所以有效,是因为 Uri错误地将原始字符串解析为相对 URI。最终用于创建 WebRequest 的 URI相当于:

new Uri(
new Uri("pack://application:,,,/"),
new Uri("pack:/Common;component/Resources/DefaultTheme/DefaultTheme.xaml"))

...产生:

pack://application:,,,/Common;component/Resources/DefaultTheme/DefaultTheme.xaml

中提琴,我们最终从一个有效的包 URI 加载资源,即使我们给它一个无效的。

我们知道“错误的”URI 有效,因为它会意外地转换为良好的 URI。至于为什么直接使用相同的“好”URI 在设计器中不起作用,这很好奇。

也许您只需要重建 Common项目和试图合并资源字典的项目。如果仍然失败,则可能是您的 UserControl.Resources有一个不同的BaseUri在设计器中运行时比在运行时运行时。让我们看看能不能找出 BaseUri 是什么?是在设计时。修改你的UserControl如下:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
xmlns:m="clr-namespace:System.Windows.Markup;assembly=System.Xaml"
x:Name="Root">
<UserControl.Resources>
<ResourceDictionary">
<Style x:Key="BaseUriTextStyle" TargetType="TextBlock">
<Setter Property="Text"
Value="{Binding ElementName=Root,
Path=Resources.(m:IUriContext.BaseUri)}" />
</Style>
</ResourceDictionary>
</UserControl.Resources>

<TextBlock Style="{StaticResource BaseUriTextStyle}" />
</UserControl>

查看设计器中显示的内容。它可能会给我们一些线索。

关于WPF pack :/[assemblyName];component/. .. vs pack ://application:, ,,/[assemblyName];component/...?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27045856/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com