Is there any way to use StaticResource in a WPF control library and be able to view at design-time?

前端 未结 3 1712
无人及你
无人及你 2021-02-04 00:29

I have a WPF Control Library that is being added to a windows forms application. We want to allow the controls to be localizable, however I am not sure how to FULLY accomplish t

相关标签:
3条回答
  • 2021-02-04 00:53

    Here's my partial solution to your problem. I haven't tried to handle loose resources, but I have some success with sharing resources between WinForms and WPF.

    • Create a class library to contain your resources in .ResX files (e.g. Resources.resx, Resources.fr.resx, etc)
    • Create your WPF controls in a WPF user control library
    • Create your WinForms host
    • Reference the resources in your resource library from WPF using the Infralution.Localization.Wpf markup extension and culture manager, e.g.

      <TextBlock Text="{Resx ResxName=ResourceLib.Resources, Key=Test}"/>
      
    • Put the content of your WPF user controls into one or more resource dictionaries as control templates,e,g

      <ControlTemplate x:Key="TestTemplate">
          <Grid>
              <Grid.RowDefinitions>
                  <RowDefinition/>
                  <RowDefinition/>
              </Grid.RowDefinitions>
      
              <TextBlock Text="{Resx ResxName=ResourceLib.Resources, Key=Test}"/>
          </Grid>
      </ControlTemplate>
      
    • Use the resource template in your user controls

      <UserControl x:Class="WpfControls.UserControl1"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" 
                   d:DesignHeight="300" d:DesignWidth="300" >
          <UserControl.Resources>
              <ResourceDictionary>
                  <ResourceDictionary.MergedDictionaries>
                      <ResourceDictionary Source="ResourceDictionary.xaml"/>
                  </ResourceDictionary.MergedDictionaries>
              </ResourceDictionary>
          </UserControl.Resources>
          <ContentControl Template="{StaticResource TestTemplate}" />
      </UserControl>
      
    • Add a couple of lines of code to make things work

      public partial class UserControl1 : UserControl
      {
          // we require a reference to the resource library to ensure it's loaded into memory
          private Class1 _class1 = new Class1();
      
          public UserControl1()
          {
              // Use the CultureManager to switch to the current culture
              CultureManager.UICulture = Thread.CurrentThread.CurrentCulture;
      
              InitializeComponent();
          }
      }
      

    Here's a simple demo app called WindowsFormsHost.7z

    0 讨论(0)
  • 2021-02-04 01:12

    I too had a problem dealing with Styling Themes and available static resources. So, I created a stand-alone library that basically had nothing but the themes to be used all nested like your MERGED resources of your prior linked question.

    Then, in the Windows form (.xaml), I just put reference to that library, something like

    <Window x:Class="MyAppNamespace.MyView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ... />
    
      <Window.Resources>
        <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
            <!-- Common base theme -->
            <ResourceDictionary   Source="pack://application:,,,/MyLibrary;component/Themes/MyMainThemeWrapper.xaml" />
            </ResourceDictionary.MergedDictionaries>
          </ResourceDictionary>
      </Window.Resources>
    
      <Rest of XAML for the WPF window>
    
    </Window>
    

    The "component" appears to refer to the root of the given "MyLibrary" project. In the actual project, I created a subfolder called "Themes", hence the source includes... ;component/Themes/...

    The "MyMainThemeWrapper.xaml" is very much like your nested Merged Resource dictionaries, and it sees everything perfectly from other libraries.

    0 讨论(0)
  • 2021-02-04 01:15

    I've run into this problem once, and I resolved it by dropping the whole "Resources are objects indexed by key in canonical dictionaries" thing.

    I mean, the simple fact of defining a resource in one project and referencing it in another by it's "key" should give goosebumps to any sane person. I wanted strong references.

    My solution to this problem was to create a custom tool that converts my resource xaml files to static classes with a property for each resource:

    So MyResources.xaml:

    <ResourceDictionary>
      <SolidColorBrush x:Key="LightBrush" ... />
      <SolidColorBrush x:Key="DarkBrush" ... />
    </ResourceDictionary>
    

    Becomes MyResources.xaml.cs

    public static class MyResources {
    
      static MyResources() {
        // load the xaml file and assign values to static properties
      }
    
      public static SolidColorBrush LightBrush { get; set; }
      public static SolidColorBrush DarkBrush { get; set; }
    
    }
    

    For referencing a resource, you can use the x:Static instead of StaticResource:

    <Border 
       Fill="{x:Static MyResources.LightBrush}"
       BorderBrush="{x:Static MyResources.DarkBrush}"
       ... />
    

    Now you got strong references, autocompletion and compile time check of resources.

    0 讨论(0)
提交回复
热议问题