使用视图模型中的XAML资源
本文关键字:XAML 资源 模型 视图 | 更新日期: 2023-09-27 18:02:26
我有几个用XAML标记声明的资源,并且希望访问视图模型中的资源。我可以很容易地使用foo.Resources["resourceKey"] or findResource("")
,但这意味着我必须将XAML和c#代码紧密地结合在一起。当我开始使用MVVM时,这不是我想要做的。
在视图模型中使用视图中定义的资源是否有最佳实践或任何方法?
更新:
资源主要是符号定义,用于定义ESRI地图中符号的外观。例如:
<esri:MarkerSymbol x:Key="SMS">
<esri:MarkerSymbol.ControlTemplate>
<ControlTemplate>
<Ellipse x:Name="Element" Margin="-7,-7,0,0" Width="14" Height="14" Fill="Blue">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Storyboard.TargetName="Element" Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)" To="Green" Duration="00:00:0.25"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Ellipse>
</ControlTemplate>
</esri:MarkerSymbol.ControlTemplate>
</esri:MarkerSymbol>
这些符号以编程方式添加到地图中,但我需要在视图模型中访问它们。
如果你真的想从视图模型层访问样式/模板,你可以做的一件事是把样式放在一个单独的ResourceDictionary(让我们假设你叫它SymbolTemplates.xaml
)中,并加载到:
var resourceDictionary = new ResourceDictionary()
{
Source = new Uri("SymbolTemplates.xaml", UriKind.Relative)
};
ControlTemplate template = resourceDictionary["SMS"] as ControlTemplate;
(我发现,如果您将SymbolTemplates.xaml
的构建操作设置为内容,这种方法效果最好。)
一种更接近mvc的方法是让视图模型层公开每个符号的"类型"。此类型将确定要应用于添加到视图中的每个符号的模板或样式。然后使用IValueConverter将符号类型转换为要应用的样式或模板。这个值转换器需要加载资源字典,但由于值转换器位于视图层,因此不会破坏MVVM。
您首先要问自己的是,为什么要从VM访问XAML资源。
有很多方法可以从VM访问和操作XAML资源,问题又来了,为什么要这样做呢?
因为例如,如果你想运行动画,你最好从VM触发一个事件并运行动画。在UI上,没有虚拟机知道这个特定的动画(查看这个例子)。
ViewModel的目标是保持它独立于ui,所以尽你最大的努力去解耦它们
您可以获得应用程序范围内的xaml资源
Application.Current.Resources["ApplicationScopeResource"] = Brushes.White;