I have several resources declared in XAML markup and would like to access the resources in my view model. I could easily use something foo.Resources["resourceKey"] or findResource("")
but that would mean that I would have to couple my XAML and C# code closely together. Not what I intended to do when I started using MVVM.
Is there a best practice or any way to use resources defined in the view in the view model?
Update:
The resources are mainly symbol definitions which are used to define the appearance of symbols in ESRI maps. For example this:
<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>开发者_JAVA百科;
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Ellipse>
</ControlTemplate>
</esri:MarkerSymbol.ControlTemplate>
</esri:MarkerSymbol>
The symbols are added programatically to the map, though I need to access them in my view model.
If you really want to access styles/templates from the view-model layer, one thing you can do is to put the styles in a separate ResourceDictionary (let's suppose you called it SymbolTemplates.xaml
) and load that in:
var resourceDictionary = new ResourceDictionary()
{
Source = new Uri("SymbolTemplates.xaml", UriKind.Relative)
};
ControlTemplate template = resourceDictionary["SMS"] as ControlTemplate;
(I found that this approach works best if you set the Build Action for SymbolTemplates.xaml
to Content.)
A more MVVM-ish approach would be to have the view-model layer expose the 'type' of each symbol. This type would determine the template or style to apply to each symbol added to the view. You'd then use an IValueConverter to convert the type of symbol into the style or template to apply. This value-converter would need to load the resource dictionary, but since value converters live in the view-layer, that doesn't break MVVM.
First think you would want to ask yourself is, why would you want to access your XAML resources from the VM.
There are many ways to access and manipulate the XAML resources from the VM, the question is again, why would you want to do that.
Because for example, if you want to run an animation, you would be better off trigger an event from the VM and run the anim. on the UI without the VM to know about this particular animation (Check out this for examples).
The goal of ViewModel is to keep it UI-independent so do your maximum to decouple them.
You can get your application-wide xaml resources
Application.Current.Resources["ApplicationScopeResource"] = Brushes.White;
精彩评论