In WPF, how do I give my custom control a default style to be used in Design Mode?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-23 18:42:31

问题


I have created a custom WPF control. The control acts as a container with various regions (so it can work like a master page).

The style for this control is loaded at runtime from a separate resource dictionary as follows:

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

My custom control's style looks as follows...

<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>

The problem is that this style is only loaded at Runtime. So in Design Mode my control does not have any style and does not have any size or layout. How can I give my control a default style for Design Mode?

Update: I'm making some progress... it appears I can specify a default theme to use in a file called Themes\Generic.xaml. This works fine in a small sample project, but for some reason my VS2008 designer stays blank when I do the same thing in my actual project... Help? :(

Note that my custom control's code looks as follows:

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());
    }

回答1:


Through lots of poking around project files I have figured out what was wrong!

  1. Themes\Generic.xaml contains your control's default Style. This is fine.
  2. Your Assembly.cs file needs to contain the following attribute:

    [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)
    )]
    

Voila! The VS2008 designer works!




回答2:


Did you try

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

as part of the constructor?




回答3:


Try moving the style to a standard place.

  • Add / New Item / Custom Control(WPF) / "MyDummyControl"
  • now place your style in "Themes/Generic.xaml" that was created
  • remove "MyDummyControl" files and style
  • remove your Theme.xaml, and MergedDictionaries



回答4:


One more thing, in my experience, using DynamicResource in a style defined in themes\generic.xaml (like you did for the Border) does not work (at least, does not work always). You should consider changing that to a StaticResource lookup.



来源:https://stackoverflow.com/questions/1232584/in-wpf-how-do-i-give-my-custom-control-a-default-style-to-be-used-in-design-mod

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!