0

Is it possible to load one of my stackpanels based on a string property inside my viewmodel? So if string is MyStackPanel1 then the appropiate stackpanel will be injected into the grid of my mainwindow.

My ResourceDictionary

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">


    <StackPanel x:Key="MyStackPanel1" Background="{Binding Color}"> 
       // Has some content     
    </StackPanel>

    <StackPanel x:Key="MyStackPanel2" Background="{Binding Color}">   
     // Has some other content
    </StackPanel>
</ResourceDictionary>

My MainWindow:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Grid>

    </Grid>
</Window>

Here an idea of the viewmodel:

public class ViewModel : INotifyPropertyChanged {
  public event PropertyChangedEventHandler PropertyChanged;
  public string StackPanelName { get; set; };
  public string Color { get; set; };

   private void ChangedHandler(string propertyToBeChanged) {

   }
}
Asperger
  • 3,064
  • 8
  • 52
  • 100
  • 1
    instead of storing `` in ResourceDictionary (warning: they are Shared) I suggest you switch to DataTemplates and use DataTemplateSelector to choose correct template based on property value (or go without DataTemplateSelector and set choose correct template via Style DataTrigger) – ASh Aug 15 '17 at 08:40
  • see some examples here: https://stackoverflow.com/questions/20468126/contentcontrol-contenttemplateselector-dynamically-select-template – ASh Aug 15 '17 at 08:44
  • @ASh ive just read https://msdn.microsoft.com/de-de/library/system.windows.controls.datatemplateselector(v=vs.110).aspx – Asperger Aug 15 '17 at 08:47
  • Why are you defining to identical StackPanels as resources to begin with? Also, a view model shouldn't have a property called "StackPanelName". – mm8 Aug 15 '17 at 10:07
  • @mm8 interesting, can you explain why? I thought pure view data and states belongs to the viewmodel. – Asperger Aug 15 '17 at 10:09
  • A view model shouldn't have any knowledge about what kind of panels that are used in the view. – mm8 Aug 15 '17 at 10:09
  • @mm8 oh, didnt know that. Thanks for the info. I actually have an answer, maybe you want to check it out. – Asperger Aug 15 '17 at 10:10
  • @mm8 Do you think its an acceptable solution? Ive posted an answer – Asperger Aug 15 '17 at 10:50

2 Answers2

1

I think I have an idea how to solve this. First I define a list of resources:

In XAML I write:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="MyResourceDictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

<Grid x:Name="Body">
    <ContentControl x:Name="Sample" ContentTemplate="{StaticResource MyResource1}"/>
</Grid>

Now in my resource dictionary:

<DataTemplate x:Key="MyResource1" x:Shared="false">
    <StackPanel>
        <TextBlock Background="{Binding background}">Hello World</TextBlock>
    </StackPanel>
</DataTemplate>

// Resource2 and so on

Then In my view I can do the following:

public void SwapResource(ContentControl contentControl, string resourceName) {
    contentControl.ContentTemplate = (DataTemplate)FindResource(resourceName);
}

Problem is that the bindings wont work...

Asperger
  • 3,064
  • 8
  • 52
  • 100
1

You could use a ContentControl with ContentTemplates but for the bindings to work you should set the Content property of the ContentControl:

<Window.Resources>
    <ResourceDictionary>
        <DataTemplate x:Key="MyResource1" x:Shared="false">
            <StackPanel>
                <TextBlock Background="{Binding background}">Hello World</TextBlock>
            </StackPanel>
        </DataTemplate>

        <!-- Resource2 and so on -->
    </ResourceDictionary>
</Window.Resources>

<Grid x:Name="Body">
    <!-- "background" is a property of the view model -->
    <ContentControl x:Name="Sample" Content="{Binding}" ContentTemplate="{StaticResource MyResource1}"/>
</Grid>
mm8
  • 163,881
  • 10
  • 57
  • 88