Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using XAML resource in view model

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>
                    </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.

like image 562
Jay Avatar asked Jul 17 '11 20:07

Jay


1 Answers

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.

like image 158
Luke Woodward Avatar answered Oct 24 '22 04:10

Luke Woodward