在WPF中,如何为自定义控件提供在设计模式下使用的默认样式?

时间:2009-08-05 11:12:06

标签: wpf styles

我创建了一个自定义WPF控件。该控件充当具有各种区域的容器(因此它可以像母版页一样工作)。

此控件的样式在运行时从单独的资源字典加载,如下所示:

<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyApp.Application;component/Themes/Theme.xaml" x:Name="theme"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

我的自定义控件的样式如下所示......

<Style TargetType="{x:Type shareduc:EditControlMaster}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type shareduc:EditControlMaster}">
                <Grid>
                    <Grid.ColumnDefinitions></Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="auto"></RowDefinition>
                        <RowDefinition Height="*"></RowDefinition>
                    </Grid.RowDefinitions>

                    <Border BorderBrush="{DynamicResource xxBorderBrush}" 
                                BorderThickness="0,1,0,1" Background="White" Grid.Row="0">
                        <Grid >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="auto"></RowDefinition>
                                <RowDefinition Height="auto"></RowDefinition>
                            </Grid.RowDefinitions>

                            <ContentPresenter Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Margin="10" Content="{TemplateBinding Image}"  />
                            <ContentPresenter Grid.Row="0" Grid.Column="1" Margin="2" Content="{TemplateBinding Title}"  />
                            <ContentPresenter Grid.Row="1" Grid.Column="1" Margin="2" Content="{TemplateBinding Abstract}"  />
                        </Grid>
                    </Border>

                    <ContentPresenter Grid.Row="1" Margin="2" Content="{TemplateBinding Content}" />

                </Grid>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

问题是此样式仅在运行时加载。因此在设计模式下,我的控件没有任何样式,也没有任何大小或布局。如何为控件设置模式提供默认样式?

更新: 我正在取得一些进展......似乎我可以在一个名为Themes \ Generic.xaml的文件中指定一个默认主题。这在一个小的示例项目中工作得很好,但由于某些原因,当我在实际项目中执行相同操作时,我的VS2008设计器保持空白...帮助? :(

请注意,我的自定义控件的代码如下所示:

public partial class EditControlMaster : Control
    {
        static EditControlMaster()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(EditControlMaster),
              new FrameworkPropertyMetadata(typeof(EditControlMaster)));
        }

        public object Title
        {
            get { return (object)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        public static readonly DependencyProperty TitleProperty =
          DependencyProperty.Register("Title", typeof(object),
          typeof(EditControlMaster), new UIPropertyMetadata());



        public object Image
        {
            get { return (object)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }

        public static readonly DependencyProperty ImageProperty =
          DependencyProperty.Register("Image", typeof(object),
          typeof(EditControlMaster), new UIPropertyMetadata());


        public object Abstract
        {
            get { return (object)GetValue(AbstractProperty); }
            set { SetValue(AbstractProperty, value); }
        }

        public static readonly DependencyProperty AbstractProperty =
          DependencyProperty.Register("Abstract", typeof(object),
          typeof(EditControlMaster), new UIPropertyMetadata());

        public object Content
        {
            get { return (object)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        public static readonly DependencyProperty ContentProperty =
          DependencyProperty.Register("Content", typeof(object),
          typeof(EditControlMaster), new UIPropertyMetadata());
    }

4 个答案:

答案 0 :(得分:5)

通过大量探索项目文件我发现了什么问题!

  1. Themes \ Generic.xaml包含控件的默认样式。这很好。
  2. 您的Assembly.cs文件需要包含以下属性:

    [assembly: ThemeInfo(
        ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
        //(used if a resource is not found in the page, 
        // or application resource dictionaries)
        ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
        //(used if a resource is not found in the page, 
        // app, or any theme specific resource dictionaries)
    )]
    
  3. 瞧! VS2008设计师工作!

答案 1 :(得分:1)

你试过吗

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

作为构造函数的一部分?

答案 2 :(得分:0)

尝试将样式移动到标准位置。

  • 添加/新建项目/自定义控制(WPF)/“MyDummyControl”
  • 现在将您的风格置于已创建的“Themes / Generic.xaml”
  • 删除“MyDummyControl”文件和样式
  • 删除您的Theme.xaml和MergedDictionaries

答案 3 :(得分:0)

根据我的经验,还有另一件事,在themes \ generic.xaml中定义的样式中使用DynamicResource(就像你为Border所做的那样)不起作用(至少,总是不起作用)。您应该考虑将其更改为StaticResource查找。