在视图模型中使用XAML资源

Jay*_*Jay 10 c# wpf resources xaml

我有几个在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>
Run Code Online (Sandbox Code Playgroud)

这些符号以编程方式添加到地图中,但我需要在我的视图模型中访问它们.

Luk*_*ard 11

如果你真的想从视图模型层访问样式/模板,你可以做的一件事就是将样式放在一个单独的ResourceDictionary中(让我们假设你调用它SymbolTemplates.xaml)并将其加载到:

var resourceDictionary = new ResourceDictionary()
{
    Source = new Uri("SymbolTemplates.xaml", UriKind.Relative)
};

ControlTemplate template = resourceDictionary["SMS"] as ControlTemplate;
Run Code Online (Sandbox Code Playgroud)

(我发现如果将Build Action设置为SymbolTemplates.xamlContent ,这种方法效果最好.)

更MVVM-ish方法是让视图模型层公开每个符号的"类型".此类型将确定要应用于添加到视图的每个符号的模板或样式.然后,您可以使用IValueConverter将符号类型转换为要应用的样式或模板.此值转换器需要加载资源字典,但由于值转换器位于视图层中,因此不会破坏MVVM.


Shi*_*mmy 6

首先想你会问自己,为什么你想从VM访问你的XAML资源.

有很多方法可以从VM访问和操作XAML资源,问题是,为什么要这样做呢.

因为,例如,如果要运行动画,最好从VM触发事件并运行动画.在没有VM的UI上知道这个特定的动画(查看这个例子).

ViewModel的目标是保持与UI无关,因此请尽量将它们分离.