Let the user change the resource dictionnary

我的未来我决定 提交于 2019-12-11 22:11:19

问题


All my styles and templates are located in a resource dictionnary named "design.xaml" so in every Usercontrol I have :

<UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyProject;component/design.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

But I'd like to let the user choose his preferred design by creating 2 resources dictionnaries with the same templates inside (same key for each template with different colors).

For example a file design.xaml and design2.xaml

How can I do that ? Is it possible to change dynamically the resource dictionnary using code ?

Thank you !


回答1:


ResourceDictionary1

<Style x:Key="StyleTitleText" TargetType="TextBlock">
    <Setter Property="FontFamily" Value="Arial" />
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="Foreground" Value="Green" />
</Style>

ResourceDictionary2

<Style x:Key="StyleTitleText" TargetType="TextBlock">
  <Setter Property="FontFamily" Value="Arial" />
  <Setter Property="FontSize" Value="14"/>
  <Setter Property="Foreground" Value="Red" />
</Style>

MainWindow xaml

You need to use DynamicResource over StaticResource if the themes need to update the UI dynamically (i.e. withoput entire UI reloading).

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

<StackPanel Orientation="Horizontal">
    <ToggleButton Name="Radiobtn" Content="Switch ResourceDictionary" Height="35"   FontSize="12" Margin="0,0,50,0"  Click="RadioButton_Checked_1"></ToggleButton>
    <TextBlock Style="{DynamicResource StyleTitleText}" Text="hfghfhgfhgfhgfghfhfhgf" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</StackPanel>

c#

  ResourceDictionary r1;
  ResourceDictionary r0;
    public MainWindow()
    {
        InitializeComponent();
        r1 = this.Resources.MergedDictionaries[1];
        r0 = this.Resources.MergedDictionaries[0];
        this.Resources.MergedDictionaries.Remove(r1);

    }

    private void RadioButton_Checked_1(object sender, RoutedEventArgs e)
    {
        this.Resources.Clear();
        if (Radiobtn.IsChecked == true)
        {
            this.Resources.MergedDictionaries.Add(r0);
        }
        else
        {
            this.Resources.MergedDictionaries.Add(r1);
        }
    }



回答2:


You can easily load a ResourceDictionary in the code behind using the following code:

ResourceDictionary resourceDictionary = new ResourceDictionary { Source = 
    new Uri("/AssemblyName;component/OptionalFolderName/ResourceDictionaryName.xaml", 
    UriKind.RelativeOrAbsolute) };
YourCurrentUserControlOrWindow.Resources.MergedDictionaries.Add(resourceDictionary);



回答3:


Assuming you have a combobox dropdown that lets user select a style, you can do the following

ViewModel with a collection of styles defined through a data model called StyleDefinition

// Showing the viewmodel constructor only
public ViewModel()
{
    this.AvailableStyles = new ObservableCollection<StyleDefinition>()
    {
        new StyleDefinition() { Name="Red", ResourceUri="Design.xaml" },
        new StyleDefinition() { Name="Green", ResourceUri="Design2.xaml" }
    };
}

// Definition of a simple data model to store style name and uri
public class StyleDefinition
    {
        public string Name { get; set; }
        public string ResourceUri { get; set; }
    }

Now bind the collection to combo box, and set a simple event handler on selectionchanged

<ComboBox Height="50" x:Name="StyleChanger" ItemsSource="{Binding Path=AvailableStyles}" 
              SelectedValuePath="ResourceUri" DisplayMemberPath="Name" 
              SelectionChanged="StyleChanger_SelectionChanged">

Selection changed code behind:

private void StyleChanger_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var style = this.StyleChanger.SelectedItem as StyleDefinition;
    this.Resources.MergedDictionaries[0].Source = new Uri(style.ResourceUri, UriKind.Relative);
}

Bottom line is that you just have to change the Source property of MergedDictionaries[0] to the one that user selects. That will change the style dynamically.



来源:https://stackoverflow.com/questions/24553184/let-the-user-change-the-resource-dictionnary

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!