简体   繁体   中英

Moving App.xaml Styles to Resource Dictionary

I have a custom control that uses styles that are in a resource dictionary that is in linked in the app.xaml. If I take the link off and add the link to the page that contains the control it doesn't work. Why is that? Why would my control (a dll) need the styles to be in the app.xaml and not just on the page that the control is contained in?

Why would my control (a dll) need the styles to be in the app.xaml and not just on the page that the control is contained in?

Custom controls need a default style. This default style is set within the constructor. eg:

public CustomControl()
{
    DefaultStyleKey = typeof(CustomControl);
}

When this is set it looks within the containing assembly for this style. If the control is within an application, then it looks within the App.xaml. If the control is within a class library, it looks within a file Generic.xaml that must be placed within a folder "Themes". You do not need to place the style within either of these files. You can create a separate file that contains the style and reference it from either App.xaml or Themes/Generic.xaml (based on where the control is defined). To do this you create a MergedDictionary within one of those files. If your control is defined in your application you would do

<Application x:Class="MyApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!--Application Resources-->
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Controls/CustomControl.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    <Application.Resources>
</Application>

If your control is defined within a class library the Themes/Generic.xaml should look like this

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/My.Custom.Assembly;component/FolderLocationOfXaml/CustomControl.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

No matter where your custom control is placed the xaml for this will always look the same

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:My.Custom.Assembly.Controls">
        <Style TargetType="local:CustomControl">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomControl">
                    <Grid>
                        <! -- Other stuff here -->
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Without this default style defined, there is no way to determine what style to override. Once the default style is defined you can change the style within your app or anywhere else the control is being used.

Try moving the style into the control to verify that all of the required references are in place for your control to use items from the dictionary. Make sure that the project containing your UserControl has a reference to the project that contains the resource dictionary. Verify your Source path to the dictionary:

<ResourceDictionary Source="/AssemblyName;component/StylesFolderName/ResourceDictionaryName.xaml" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM