代码之家  ›  专栏  ›  技术社区  ›  David Veeneman

开始使用派生自定义控件?

  •  1
  • David Veeneman  · 技术社区  · 14 年前

    我正在尝试派生自定义控件,并创建了我认为最简单的可能派生:

    • 我在Vs2010中创建了一个自定义控件项目,并将CustomControl1的基类从 Control Calendar .

    • 然后我进入generic.xaml并删除了为CustomControl1创建的默认样式。

    • 最后,我创建了一个WPF应用程序来使用控件。

    当我将自定义控件添加到应用程序的主窗口时,我希望看到一个常规的WPF日历,因为我从 历法 并且未对日历控件模板进行任何更改。

    相反,在设计时或运行时不会显示任何内容。主窗口仍为空。我不知道发生了什么,但很明显我在这条线上的某个地方做了一个错误的假设。

    有人能帮我清理一下吗?谢谢你的帮助。

    顺便问一下——我为什么要这样做?我正在扩展日历控件,但只需要修改CalendarDayButton控件模板。在我进行修改之前,我想我应该能够首先显示未修改的日历。就像我说的,我想我在某个地方做了一个错误的假设。

    自定义控件1.cs 以下是CustomControl1的代码:

    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfCustomControlLibrary1
    {
         public class CustomControl1 : Calendar
         {
              static CustomControl1()
              {
                   DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
              }
         }
    }
    

    XAML 下面是generic.xaml的标记,它位于控件的主题文件夹中:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfCustomControlLibrary1">
    
    
    </ResourceDictionary>
    

    主窗口 最后,这里是mainwindow.xaml标记:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    
            xmlns:WpfCustomControlLibrary1="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1" Title="MainWindow" Height="350" Width="525">
        <Grid>
            <WpfCustomControlLibrary1:CustomControl1 />
        </Grid>
    </Window>
    

    wpfApplication1包含对wpfCustomControlLibrary1项目的引用。

    3 回复  |  直到 12 年前
        1
  •  4
  •   NVM    12 年前

    defaultStyleKeyProperty.overrideMetadata(typeof(customControl1),new frameworkProperties(typeof(customControl1));

    ->此行所说的是,customControl1在generic.xaml中定义了其默认样式。

    然后我进入generic.xaml并删除了为CustomControl1创建的默认样式。

    ->这将删除CustomControl1的默认样式

    所以你的控件没有样式,所以它不显示任何内容:d

    您应该复制日历控件的样式并将TargetType更改为CustomControl1,或者创建新样式并添加Basedon日历,而不是从Generic.xaml中删除样式。

    编辑 在下面大卫的回答中添加一点信息,让那些有远见的人了解更多信息。

    <Style TargetType="{x:Type local:FsCalendar}" BasedOn={x:Type Calender}>
        <Setter Property="CalendarDayButtonStyle" Value="{StaticResource FsCalendarDayButtonStyle}" />
    </Style>
    

    这就是你所需要的风格。Basedon将负责从默认样式复制所有内容 它还将处理不同的主题。如果您从日历的默认主题中复制样式,那么除了从中复制“默认”样式的主题外,您将中断对所有主题的查找。

        2
  •  1
  •   David Veeneman    14 年前

    我找到了我的答案——感谢NVM的帮助!这通常适用于控件,但特别适用于日历控件。如果只修改控件的一部分,则不必包括所有组成控件模板。

    但是,您必须包含主控件模板(指向自定义控件),并且必须建立从主控件到要修改的模板的链。对于我的日历控件,我只需要修改 CalendarDayButton 用于实现我要进行的更改的模板。所以,我是这样做的:

    • 我包含了主日历模板,并将其指向我的自定义控件。

    • 然后,为了深入到CalendarDayButton,我添加了一个属性设置器来指向我的主日历样式 CalendarDayButtonStyle 属性设置为我的自定义日历天按钮样式。

    下面是我的generic.xaml文件中的主日历样式声明的外观:

    <!-- Calendar Style -->
    <Style TargetType="{x:Type local:FsCalendar}">
        <Setter Property="CalendarDayButtonStyle" Value="{StaticResource FsCalendarDayButtonStyle}" />
    ...
    </Style>
    

    主日历样式的其余部分不变——它是默认样式的副本。

    另外,calendarAybutton样式定义必须出现在generic.xaml中的主日历样式定义之前,否则主日历样式将找不到它。

    我写了一篇题为 Extending the WPF Calendar Control . 它完成了扩展复杂控件(如WPF日历)的步骤。希望它能帮助其他解决同样问题的人。

        3
  •  0
  •   David Veeneman    14 年前

    顺便说一句,我已经发现了style.basedon属性,它允许您从现有样式派生样式,而不必重复基本样式。有一个 good blog post on it here .