引用ResourceDictionaries以及跨多个程序集样式化的问题

时间:2018-12-13 15:58:36

标签: c# wpf xaml

我在跨多个程序集引用ResourceDictionaries(RD)时遇到问题。

我目前遇到的具体问题是,资源和样式是在设计时而不是在运行时应用于LoginWindow的。

我还想确定RD /资源是否以与DataContext相同的方式工作。

我有点机智,我想我缺少关于WPF如何处理RD和资源等的一些基本知识

对于上下文,我有两个正在使用的程序集。

  • ControlsAndResources(包含常规控件和资源/样式)
  • 登录(处理登录ui和逻辑;其中包含对ControlsAndResources的引用)

ControlsAndResources程序集包含5个简单的RD。 这些都放在/ Styles / Default

  • Base.xaml(包含FrameworkElement和控件的基本样式)
  • Buttons.xaml(继承自基本控件样式)
  • Textblocks.xaml(继承自Base FrameworkElement样式)
  • Textboxes.xaml(继承自基本控件样式)
  • Package.xaml(将“ Buttons.xaml”,“ Textblocks.xaml”和“ Textboxes.xaml”打包到一个RD中,并包含另一个RD,用于为“ Button”,“ Textblock”和“文本框的类型)

Login程序集包含LoginWindow.xaml。 (这包含对“ Package.xaml”的引用,其意图是隐式样式将应用于“ LoginWindow”中包含的“ Textblock”,“ Textbox”和“ Button”-它们仅在设计时使用,而不是在运行时)

我注释掉了对“ DefaultStyles.xaml” RD的引用,该引用实际上只是封装了相同的“ Package.xaml” RD。出于某种原因,我认为解决方案是在同一装配中创建物理RD,然后再从其他装配中引用我想要的RD。不。

我对WPF相当熟练并且很熟悉,这个主题是个例外,因为我只是开始提取样式以分离RD。我推迟了,因为与经理打交道似乎很头疼。到目前为止,看来我是对的。但是,我决定从此开始,以真正遵守DRY原则。 话虽这么说,但根据目前的代码,尽管琐碎,但如果有人对DRY原则有更好的坚持的建议(或确实有任何建议),那么我就会耳熟能详。

谢谢。

PS-我尝试将所有内容从StaticResource更改为DynamicResource,但这会引发异常,无论我在何处进行更改。

System.Windows.Markup.XamlParseException:无法在类型为'Style'的'BasedOn'属性上设置'DynamicResourceExtension'。只能在DependencyObject的DependencyProperty上设置“ DynamicResourceExtension”。

~~~~~~~~~~~~~~~~~~~~ Base.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
    <Style TargetType="{x:Type FrameworkElement}" x:Key="BaseDefaultFrameworkElement">
        <Setter Property="Margin" Value="5"/>
    </Style>

    <Style TargetType="{x:Type Control}" x:Key="BaseDefaultControl" BasedOn="{StaticResource BaseDefaultFrameworkElement}">
        <Setter Property="Padding" Value="5"/>
    </Style>
</ResourceDictionary>


~~~~~~~~~~~~~~~~~~~~ Package.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Buttons.xaml"/>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textblocks.xaml"/>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textboxes.xaml"/>
        <ResourceDictionary>
            <Style TargetType="Button" BasedOn="{StaticResource DefaultButtons}"/>
            <Style TargetType="TextBlock" BasedOn="{StaticResource DefaultTextblocks}"/>
            <Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextboxes}"/>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

~~~~~~~~~~~~~~~~~~~~ Buttons.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
        <ResourceDictionary>
            <Style TargetType="Button" x:Key="DefaultButtons" BasedOn="{StaticResource BaseDefaultControl}"/>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


~~~~~~~~~~~~~~~~~~~~ Textblocks.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
        <ResourceDictionary>
            <Style TargetType="TextBlock" x:Key="DefaultTextblocks" BasedOn="{StaticResource BaseDefaultFrameworkElement}"/>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


~~~~~~~~~~~~~~~~~~~~ Textboxes.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
        <ResourceDictionary>
            <Style TargetType="TextBox" x:Key="DefaultTextboxes" BasedOn="{StaticResource BaseDefaultControl}"/>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

~~~~~~~~~~~~~~~~~~~~ LoginWindow.xaml ~~~~~~~~~~~~~~~~~~~~
<Window x:Class="Login.LoginWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Login"
        SizeToContent="WidthAndHeight"
        Title="{Binding WindowTitle, FallbackValue=Login, TargetNullValue=Login}">
    <Window.Resources>
        <ResourceDictionary Source="pack://application:,,,/ControlsAndResources;component/Styles/Default/Package.xaml"/>
        <!--<ResourceDictionary Source="pack://application:,,,/Login;component/Resources/XAML/DefaultStyles.xaml"/>-->
    </Window.Resources>
    <Grid>
        <StackPanel>
            <TextBlock>This is a textblock</TextBlock>
            <Button>This is a button</Button>
            <TextBox>This is a textbox</TextBox>
        </StackPanel>
    </Grid>
</Window>

~~~~~~~~~~~~~~~~~~~~ DefaultStyles.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:Login.Resources.XAML">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Package.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

1 个答案:

答案 0 :(得分:1)

Package.xaml中的隐式样式应在合并的ResourceDictionary本身中定义。试试这个:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Buttons.xaml"/>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textblocks.xaml"/>
        <ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textboxes.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <Style TargetType="Button" BasedOn="{StaticResource DefaultButtons}"/>
    <Style TargetType="TextBlock" BasedOn="{StaticResource DefaultTextblocks}"/>
    <Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextboxes}"/>
</ResourceDictionary>