我将应用程序转换为DLL库,其中我的主窗口成为用户控件。我正在使用手动创建System.Windows.Application
对象的方法来存储我的资源,但我希望远离它并让我的用户控件自给自足,所以我可以简单地执行以下操作:
CustomUserControl control = new CustomUserControl ( object_to_pass);
然后在内部处理其他所有事情。控件的基本布局是一个托管多个页面的框架,如向导式应用程序。
我有两个主要问题:
设置对视图模型的引用
我认为不是使用我广泛使用的System.Windows.Application.FindResource
,而是在用户控件类上使用类似的函数,并通过单例传递对用户控件的引用。
为此,我在名为' ViewModelLocator'的类中使用mvvm-light的SimpleIoc容器。跟踪所有视图模型。问题是,这是从用户控件的datacontext绑定加载的App.xaml
中的资源。
这不能再做了,因为用户控件本身必须在其自己的xaml中进一步实例化包含它的资源:
<UserControl x:Class="WUP.Views.WarmUpPluginUserControl"
mc:Ignorable="d"
...
...
<!--This will not work-->
DataContext="{Binding Source={StaticResource Locator}, Path=MainWindowLogic}">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Path/To/ViewModelLocator/Resource.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
现在我必须在后面的用户控制代码中实例化ViewModel定位器,并将其设置为Resources.Add
的资源。这迫使我从所有其他视图(Pages)切换到ViewModel定位器的所有引用的动态资源。这不仅会导致进一步描述的问题,而且丑陋,因为我无法再使用以前的路径访问成员函数:
DataContext="{Binding Source={StaticResource Locator}, Path=MainWindowLogic}">
引用xaml中的资源,动态与静态
我使用的资源是画笔,颜色,模板和转换器,每个都在自己的资源字典中,我按正确的顺序添加它们以避免依赖性问题。
第一部分中的方法可以通过引用单例中的用户控件从ViewModel访问资源。现在的问题是如何在应用程序的每个视图中加载资源。我尝试了将它们全部粘贴在Page.Resources
或UseControl.Resources
中的强力方法,但这给了我一些页面中找不到资源的错误,尽管它们存在于那里。我正在调查为什么会发生这种情况,但我不确定
然后我尝试了创建单例类的Dr.WPF's方法,您可以使用该方法创建单个资源实例并将它们作为依赖属性公开。这迫使我再次使用动态资源来查看所有视图。
除了转换器之外,这对我的所有资源都很好,并且我最初以这种方式引用的所有转换器都会出错:
Visibility="{Binding Functions.DictatesActions, Converter={StaticResource BooleanToVisibilityConverter}, UpdateSourceTrigger=PropertyChanged}"
所以我不知道如何处理这是动态情景。
我正在考虑放弃这种方法,只使用System.Windows.Application
来存储我的所有资源,尽管它可能会导致托管应用程序中的其他用户控件出现问题(winforms)。如果有更好的方法,请告诉我!
答案 0 :(得分:0)
我终于设法解决了我的问题:
设置对视图模型的引用
在这里,我只需要从后面的代码中完成所有操作。正如我所提到的,我使用ViewModelLocator来跟踪我的所有虚拟机,因此我将引用设置为实际用户控件构造函数中的资源:
Resources["Start"] = view_model_locator.Start;
Resources["SelectUnit"] = view_model_locator.SelectUnit;
Resources["HardwareChecks"] = view_model_locator.HardwareChecks;
Resources["ConfigurationChecks"] = view_model_locator.ConfigurationChecks;
...
然后我在ViewModel定位器中将对用户控件的引用包含为static属性:
ViewModelLocator.WarmUpPluginUserControl = this;
然后我可以在其代码中的其他视图中访问它,如下所示:
DataContext = ViewModelLocator.WarmUpPluginUserControl.FindResource("Start");
我也可以在VM中使用它,就像我使用Application.Current.FindResource()一样。这不是最优雅的解决方案,但它有效
引用xaml中的资源,动态与静态
在这里,我坚持使用强力方法将所有资源都包含在每个页面的顶部:
<WUP:WUPPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/WarmUpPlugin;component/Resources/Colors.xaml"/>
<ResourceDictionary Source="pack://application:,,,/WarmUpPlugin;component/Resources/Styles.xaml"/>
...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
这确实给我带来了问题,因为我发现资源没有发现错误,但这是因为我的一些字典有其他依赖,所以我不得不通过MergedDictionaries将它们添加到相关的字典中。
当应用程序是独立的时,我没有注意到这个依赖性问题,因为所有必需的资源都已经加载到应用程序范围内。
我打算用Dr WPF方法替换它,但我仍然需要将所有我的XAML引用从static更改为动态,然后处理无法通过动态资源引用访问的转换器。