Search code examples
c#wpfxamluwpxaml-islands

How to use Windows 10 style resource in WPF with XAML Islands


I'm using XAML Islands to make my app and I want to use Windows 10 styling in my WPF app like here. For example <TextBlock Text="Header" Style="{StaticResource HeaderTextBlockStyle}"/> would result in:

enter image description here

But this doesn't work in WPF (It does work in UWP without any modifications), my understanding is that XAML Islands should make it possible. When I try to simply add the code above to my xaml file I get the exception

Cannot find resource named 'HeaderTextBlockStyle'. Resource names are case sensitive.

I get the same exception if I add Style="{StaticResource HeaderTextBlockStyle}" to a <xamlhost:WindowsXamlHost> element.

So I tried to add the controls with code so I added this WindowsXamlHost control as a stackpanel:

<xamlhost:WindowsXamlHost InitialTypeName="Windows.UI.Xaml.Controls.StackPanel" ChildChanged="WindowsXamlHost_ChildChanged"/>

And added this method (an event handler that is ran when the control is made. Learned it from this) that handles adding additional controls (a TextBlock) to the StackPanel:

private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
    { 
        // Get the host control
        WindowsXamlHost host = (WindowsXamlHost)sender;
        // Get the StackPanel in the host
        Windows.UI.Xaml.Controls.StackPanel sp = (Windows.UI.Xaml.Controls.StackPanel)host.Child;
        // Make a TextBlock to add to the StackPanel
        Windows.UI.Xaml.Controls.TextBlock textBlock = new Windows.UI.Xaml.Controls.TextBlock();
        // Set the text of the TextBlock
        textBlock.Text = "LockCursorInMonitor";
        // Get the style resources, cast them to the appropriate type for XAML Islands and add them to the TextBlock
        textBlock.Style = (Windows.UI.Xaml.Style)Application.Current.Resources["HeaderTextBlockStyle"];

        // Another way to get resources but this doesn't work too.
        //textBlock.Style = (Windows.UI.Xaml.Style)this.FindResource("HeaderTextBlockStyle");

        // Add the TextBlock to the stackpanel
        sp.Children.Add(textBlock);
    }

The Application.Current.Resources["HeaderTextBlockStyle"] way does nothing and doesn't throw an exception.

The this.FindResource("HeaderTextBlockStyle") way throws the next exception:

System.Windows.ResourceReferenceKeyNotFoundException: ''HeaderTextBlockStyle' resource not found.'

So how can I get these style resources in my WPF app?


Solution

  • One way to achieve this is to use the package ModernWPF but then you lose all the benefits of XAML Islands (if there are any. Everything I needed from XAML Islands is in ModernWPF and is easier to implement).

    After installing and setting ModernWPF up you can simply use the <TextBlock Text="Header" Style="{StaticResource HeaderTextBlockStyle}"/> way and it just works.