gpt4 book ai didi

c# - 设计时如何在 Prism 模块中使用资源字典?

转载 作者:太空狗 更新时间:2023-10-29 20:05:53 25 4
gpt4 key购买 nike

我在 silverlight 应用程序中使用 prism 框架,在单独的 XAP 中有多个模块。

我在我的 shell 项目中定义了一个资源字典。在我的模块中,我可以很好地使用资源,但由于模块在运行时加载之前与外壳分离,因此设计器不会显示或识别它们。

有没有办法让模块在设计时知道我的资源,而无需在每个 View xaml 中合并我的资源文件?

我的资源文件在“公​​共”项目中。

最佳答案

我认为我绝对有设计时资源的解决方案。

好处:

  1. 它适用于任何基于模块(MEF、UNITY..)的应用程序。
  2. 它适用于任何设计器(Visual Studio、Blend..)
  3. 它不会创建同一个 ResourceDictionary 的多个实例

让我们考虑以下解决方案:

  • MyApp.Shell (.exe)
  • MyApp.Module1 (.dll) - 使用 MEF 在运行时加载
  • MyApp.Module2 (.dll) - 使用 MEF 在运行时加载
  • MyApp.Common (.dll) - 被所有项目引用

您可以在 MyApp.Common 中定义画笔、隐式样式、模板等。

使用我的 SharedResourceDictionary 将 ResourceDictionary 包含在所有项目中。在设计时,它将为每个设计者加载 ResourceDictionary,在运行时,ResourceDictionary 将仅在必要时加载。

使用示例:

在 App.xaml 中包含 SharedResourceDictionary

<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<common:SharedResourceDictionary SharedSource="MyApp.Common;component/CommonResources.xaml" />
</ResourceDictionary>
</Application.Resources>

在设计者找不到的地方包含 SharedResourceDictionary 一些共享资源,例如在 MyApp.Module1/UserControl1.xaml

<UserControl.Resources>
<common:SharedResourceDictionary SharedSource="MyApp.Common;component/CommonResources.xaml" />
</UserControl.Resources>

来源:

/// <summary>
/// Loads singleton instance of ResourceDictionary to current scope;
/// </summary>
public class SharedResourceDictionary : ResourceDictionary
{
/// <summary>
/// store weak references to loaded ResourceDictionary, to ensure that ResourceDictionary won't be instanciated multiple times
/// </summary>
protected static Dictionary<string, WeakReference> SharedResources = new Dictionary<string, WeakReference>();

public string SharedSource
{
get { return _SharedSource; }
set
{
if (_SharedSource != value)
{
_SharedSource = value;
sharedSourceChanged();
}
}
}
private string _SharedSource;


private void sharedSourceChanged()
{
//ResourceDictionary will be instanciated only once
ResourceDictionary sharedResourceDictionary;

lock (SharedResources)
{
WeakReference weakResourceDictionary = null;
if (SharedResources.ContainsKey(_SharedSource))
{
weakResourceDictionary = SharedResources[_SharedSource];
}
else
{
SharedResources.Add(_SharedSource, null);
}

if (weakResourceDictionary == null || !weakResourceDictionary.IsAlive) //load ResourceDictionary or get reference to exiting
{
sharedResourceDictionary = (ResourceDictionary)Application.LoadComponent(new Uri(_SharedSource, UriKind.Relative));
weakResourceDictionary = new WeakReference(sharedResourceDictionary);
}
else
{
sharedResourceDictionary = (ResourceDictionary)weakResourceDictionary.Target;
}

SharedResources[_SharedSource] = weakResourceDictionary;
}


if (Application.Current != null)
{
//if sharedResourceDictionary is defined in application scope do not add it to again to current scope
if (containsResourceDictionary(Application.Current.Resources, sharedResourceDictionary))
{
return;
}
}

this.MergedDictionaries.Add(sharedResourceDictionary);
}

private bool containsResourceDictionary(ResourceDictionary scope, ResourceDictionary rs)
{
foreach (var subScope in scope.MergedDictionaries)
{
if (subScope == rs) return true;
if (containsResourceDictionary(subScope, rs)) return true;
}
return false;
}
}

关于c# - 设计时如何在 Prism 模块中使用资源字典?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7095179/

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