복합 WPF (PRISM) 모듈 리소스 데이터 템플릿
-
19-09-2019 - |
문제
Microsoft CompoisteWPF (Prism V2)를 사용하여 쉘 애플리케이션과 몇 개의 개별 모듈 프로젝트가 있다는 점을 감안할 때 ...
명령을 받으면 모듈은 새로운 뷰 모델을 생성하여 지역 관리자를 통해 지역에 추가합니다.
var viewModel = _container.Resolve<IMyViewModel>();
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel);
그런 다음 모듈 내에 리소스 사전을 만들고로드 된 뷰 모델 유형에 대한보기를 표시하기 위해 데이터 템플릿을 설정할 수 있다고 생각했습니다 (아래 XAML 참조). 그러나보기 모델이보기에 추가되면, 내가 얻는 모든 것은 네임 스페이스가 인쇄 된 뷰 모델입니다.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Modules.Module1.ViewModels"
xmlns:vw="clr-namespace:Modules.Module1.Views"
>
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<vw:MyView />
</DataTemplate>
</ResourceDictionary>
편집하다:
app.xaml에 추가하여 작동하게 할 수 있습니다.
<Application.Resources>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Module1;component/Module1Resources.xaml"/>
<ResourceDictionary Source="pack://application:,,,/Module2;component/Module2Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</Application.Resources>
괜찮지 만 새 모듈이 만들어지면 app.xaml 파일을 추가해야한다는 것을 의미합니다. 내가 찾고있는 것은 모듈이 Application.Resources에 동적으로 추가하기 위해로드하기 때문에 모듈의 방법입니다. 이게 가능해?
해결책 2
각 모듈의 초기화 내에서 응용 프로그램 리소스에 추가 할 수 있습니다.
Application.Current.Resources.MergedDictionaries
.Add(new ResourceDictionary
{
Source = new Uri(
@"pack://application:,,,/MyApplication.Modules.Module1.Module1Init;component/Resources.xaml")
});
또는 각 모듈의 협약을 따르면 "resources.xmal"이라는 리소스 사전이 있습니다.
protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new ModuleCatalog();
AddModules(catalog,
typeof (Module1),
typeof(Module2),
typeof(Module3),
typeof(Module4));
return catalog;
}
private static void AddModules(ModuleCatalog moduleCatalog,
params Type[] types)
{
types.ToList()
.ForEach(x =>
{
moduleCatalog.AddModule(x);
Application.Current.Resources.MergedDictionaries
.Add(new ResourceDictionary
{
Source = new Uri(string.Format(
@"pack://application:,,,/{0};component/{1}",
x.Assembly,
"Resources.xaml"))
});
});
}
다른 팁
쉘 앱이 모듈과 모듈에 대해 어떤 식 으로든 쉘에 도달하지 못하게하려면 다음과 같은 모듈에 대한 인터페이스를 제공 할 것입니다.
IMergeDictionaryRegistry
{
void AddDictionaryResource(Uri packUri);
}
모듈 코드 에서이 인터페이스를 요청합니다.
public class MyModule : IModule
{
IMergeDictionaryRegistry _merger;
public MyModule(IMergeDictionaryRegistry merger)
{
_merger = merger;
}
public void Initialize()
{
_merger.AddDictionaryResource(new Uri("pack://application:,,,/Module1;component/Module1Resources.xaml");
}
}
그런 다음 쉘에서 이것을 구현하여 다음을 수행합니다.
public MergeDictionaryRegistry : IMergeDictionaryRegistry
{
public void AddDictionaryResource(Uri packUri)
{
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
{
Source = packUri;
});
}
}
그리고 마지막으로 Bootstrapper의 configeRecontainer에서 :
public override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IMergeDictionaryRegistry, MergeDictionaryRegistry>();
}
이것은 당신이 원하는 기능을 얻을 것입니다 그리고 쉘과 모듈은 서로 독립적으로 유지됩니다. 이것은 당신이 당신이 회전 할 필요가 없다는 점에서 더 테스트 가능하다는 이점을 가지고 있습니다. Application
모듈 코드를 테스트하려면 (조롱 IMergeDictionaryRegistry
그리고 당신은 끝났습니다).
이것이 당신을 위해 어떻게되는지 알려주세요.
모든 것이 많은 일처럼 보입니다!
개인적으로, 나는 단지 내 견해에서 자원 사전을 선언합니다. UserControl.Resources
이런 섹션 ...
<UserControl.Resources>
<ResourceDictionary Source="../Resources/MergedResources.xaml" />
</UserControl.Resources>
병합 된 사전은 내가 포함 해야하는 모든 자원을 가리 킵니다.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Iconography.xaml" />
<ResourceDictionary Source="Typeography.xaml" />
</ResourceDictionary.MergedDictionaries>
당신은 당신의 데이터 템플릿을 거기에 선언 할 것입니다.
HTH.