tags:

views:

3195

answers:

3

I've got style resources in WPF working so that in my App.xaml I can define whether the customer or administrator layout is used. This works nicely by getting all the style out of the main XAML in a HTML/CSS-like fashion.

Now how do I make this dynamic so that I can click on a button in my application and switch the layout between customer and administrator at runtime?

Addendum:

Thanks Meeh for the links, so I made this and when I debug, it steps through all the lines but still doesn't change the layout, what else do I need to do so that the layout changes at runtime?

private void Button_Switch_Layout_Click(object sender, RoutedEventArgs e)
{
    string layoutIdCode = "administrator";

    switch (layoutIdCode)
    {
        case "administrator":
            langDictPath = "Resources/AdministratorLayout.xaml";
            break;

        case "customer":
            langDictPath = "Resources/CustomerLayout.xaml";
            break;
    }

    Uri langDictUri = new Uri(langDictPath, UriKind.Relative);
    ResourceDictionary langDict = Application.LoadComponent(langDictUri) as ResourceDictionary;
    Application.Current.Resources.MergedDictionaries.Clear();
    Application.Current.Resources.MergedDictionaries.Add(langDict);
}

 

Original Code:


App.xaml:

<Application x:Class="TestMvvm8837.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/CustomerLayout.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Window1.xaml:

<Window x:Class="TestMvvm8837.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Style="{StaticResource MainWindow}"
    Title="Resource Test" >
    <DockPanel>

        <Grid Style="{StaticResource Form}">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

            <TextBlock Style="{StaticResource FormLabel}" Grid.Column="0" Grid.Row="0" Text="First Name" />
            <TextBlock Style="{StaticResource FormLabel}" Grid.Column="0" Grid.Row="1" Text="Last Name" />
            <TextBlock Style="{StaticResource FormLabel}" Grid.Column="0" Grid.Row="2" Text="E-Mail" />

            <TextBox Grid.Column="1" Grid.Row="0"/>
            <TextBox Grid.Column="1" Grid.Row="1"/>
            <TextBox Grid.Column="1" Grid.Row="2"/>

            <Button Style="{StaticResource FormSaveButton}" Grid.Column="1" Grid.Row="3" Content="Save"/>

        </Grid>

    </DockPanel>
</Window>

AdministratorLayout.xaml:

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

    <Style x:Key="MainWindow" TargetType="{x:Type Window}">
        <Setter Property="Width" Value="800"/>
        <Setter Property="Height" Value="600"/>
    </Style>

    <Style x:Key="Form" TargetType="{x:Type Grid}">
        <Setter Property="Margin" Value="20"/>
    </Style>

    <Style x:Key="FormLabel" TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>

    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="Width" Value="200"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
    </Style>

    <Style x:Key="FormSaveButton" TargetType="{x:Type Button}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Cursor" Value="Hand"/>
    </Style>

</ResourceDictionary>

CustomerLayout.xaml:

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

    <Style x:Key="MainWindow" TargetType="{x:Type Window}">
        <Setter Property="Width" Value="600"/>
        <Setter Property="Height" Value="480"/>
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush EndPoint="1.156,1.133" StartPoint="-0.033,0.019">
                    <GradientStop Color="#FFFFFFFF" Offset="0"/>
                    <GradientStop Color="#FF4FADD3" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="Form" TargetType="{x:Type Grid}">
        <Setter Property="Margin" Value="5"/>
    </Style>

    <Style x:Key="FormLabel" TargetType="{x:Type TextBlock}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="10"/>
    </Style>

    <Style TargetType="{x:Type TextBox}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="Width" Value="200"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
    </Style>

    <Style x:Key="FormSaveButton" TargetType="{x:Type Button}">
        <Setter Property="Margin" Value="10"/>
        <Setter Property="FontFamily" Value="Verdana"/>
        <Setter Property="FontSize" Value="10"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="Cursor" Value="Hand"/>
    </Style>

</ResourceDictionary>
A: 

Use resource dictionaries

.. and switch them at runtime :)

Good luck

(Oh, and sorry for my laziness :P )

cwap
A: 

You should:

  • Load the Resource Dictionary using XamlReader in which you have defined the new style
  • Get the reference to the new style from the loaded resource ( newStyle = (Style)resource["styleName])
  • Set the new style on the control: control.Style = newStyle

HTH

bye

ema
+3  A: 

You need to be using DynamicResource inside Window1.xaml instead of StaticResource. StaticResource is only evaluated once, whereas DynamicResource actually listens for changes.

Bryce Kahle