在后面的代码中创建的控件没有它的默认样式

时间:2014-08-18 20:04:01

标签: wpf wpf-controls

我试图在窗口的代码后面实例化一个控件(用于帧导航)。不幸的是,它没有应用默认样式。

我希望在首次渲染控件时,渲染器会将控件的样式/模板设置为(显式提供的一个 - >资源中提供的默认值 - > null)。

我的心智模型是如何应用默认样式的错误?它实际上是如何

class Whatever
{
    int value = 5;
}

的语法糖
class Whatever
{
    public Whatever()
    {
        this.value = 5;
    }

    int value;
}

因此Style是在编译时设置的吗?

这可能是一个问题源于我如何访问控件的样式和模板(不太可能,因为我可以在我的主窗口上控制它的类型并且它具有默认样式)?

MainWindow.xaml

<Window>
    <Window.Resources>
        <ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="DataLogPage/Themes.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <!-- Data here... -->
</Window>

DatalogPage / Themes.xaml

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Themes/Styles/DefaultStyle.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

DatalogPage /主题/样式/ DefaultStyle.xaml

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="../Templates/DefaultTemplate.xaml" />
    </ResourceDictionary.MergedDictionaries>
    <Style TargetType="this:DataLog">
        <Setter Property="Template"
                Value="{StaticResource DefaultTemplateForDataLog}" />
    </Style>
</ResourceDictionary>

DatalogPage /主题/模板/ DefaultTemplate.xaml

<ResourceDictionary>
    <ControlTemplate x:Key="DefaultTemplateForDataLog"
                     TargetType="this:DataLog">
        <!-- Data here... -->
    </ControlTemplate>
</ResourceDictionary>

MainWindow.xaml.cs(我在后面的代码中创建控件)

private void currentContext_ContextChangeRequested()
{
    //Other bits of logic for context switching

    //User wants to go to the Data Log Page
    this.MainFrame.Navigate(new DataLogPage.DataLog());
    return;
}

重申:

问题: 在后面的代码中创建的控件没有它的默认样式。

关于为什么会出现这种情况的可能想法:

1)我的用户模型如何应用默认样式是错误的,我必须明确设置它  2)我可能错误地引用了这种风格。

如果我必须明确设置样式/模板,那么我是否可以在MainWindow的xaml中创建一些我可以通过编程方式引用的内容:new DataLogPage.DataLog(){Style = this.DataLogStyle};

1 个答案:

答案 0 :(得分:0)

<强>的App.xaml

如果您真的想要共享内容,可以将它们注入共享应用程序资源,或者您可以将它们合并到app.xaml中

<Application x:Class="BlaBla"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
   <Application.Resources>
     <ResourceDictionary>
       <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="A.xaml"/>
          <ResourceDictionary Source="B.xaml"/>
       </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>
</Application>

Using a global ResourceDictionary in a UserControl Library

WPF - Global Style?

模板和客户控制

仅适用于customcontrols(**)

首先,我永远不会在窗口中开始合并或使用字典(如果你采用cc方式,你可以将这些字典合并到下面描述的通用文件中,注意它们必须在范围内)。 你有一个名为Generic的文件夹,它必须有一个名为 Themes.xaml 的文件。就个人而言,我合并了很多字典这里,还做了一些“体力劳动”。通常我会调用我的客户控制Foo的主题ThemeName.generic.xaml,但这只是我的偏好。 :)。

自定义控件应该从控件中运行,它必须具有以下静态构造函数,才能应用它的模板。

public class Whatever : Control // from scratch or something you want to extend
   static Whatever()
   {
       DefaultStyleKeyProperty.OverrideMetadata(typeof (Whatever), new FrameworkPropertyMetadata(typeof (Whatever)));
   }
}

<Style TargetType="{x:Type local:Whatever}">
    <!-- Do whatever here ;) -->
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:Whatever}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

覆盖OnApplyTemplate以查看是否已应用模板。 (*)

<强>样式

适用于样式。

要覆盖现有控件模板,请在themes.xaml中执行以下操作。这将使您的所有按钮控件默认具有此样式。

 <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/> 
 </Style>

我经常直接将样式放在usercontrol的资源中,但主要是数据,itemptemplates等,如果它们不属于cust控件,反正这是如何做到的:

<UserControl.Resources>
    <!-- usuallly  just datatemplates, itemtemplates etc.. -->
    <Style x:Key="SomeStyle" TargetType="{x:Type Button}">
        <!--whatever -->
        <Setter Property="Background" Value="Black"/>
    </Style>
</UserControl.Resources>
<Button Style="{StaticResource SomeStyle}"></Button>

BTW:您可以动态地加载大多数东西,甚至可以从其他组件加载。资源,模板的工作原理。但这是另一个主题:)

希望它对你有所帮助,

干杯

了Stian