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

时间:2010-08-19 18:51:52

标签: wpf custom-controls

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

  • 我在VS 2010中创建了一个自定义控件项目,并将CustomControl1的基类从Control更改为Calendar

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

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

当我将自定义控件添加到应用程序的MainWindow时,我原本希望看到一个常规的WPF日历,因为我是从Calendar派生的,并且没有对Calendar控件模板进行任何更改。

相反,在设计时或运行时都没有显示任何内容。 MainWindow仍然是空的。我不确定发生了什么,但很明显我在某个地方做了一个错误的假设。

任何人都可以为我清除这个吗?谢谢你的帮助。

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

CustomControl1.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)));
          }
     }
}

Generic.xaml 这是Generic.xaml的标记,它位于控件的Themes文件夹中:

<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 个答案:

答案 0 :(得分:4)

DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1),new FrameworkPropertyMetadata(typeof(CustomControl1)));

- &gt;这一行说的是CustomControl1在Generic.xaml中定义了默认样式

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

- &GT;这样做是删除CustomControl1的默认样式

所以你的控件没有风格所以它什么都没显示:D

您应该复制Calender控件的样式并将TargetType更改为CustomControl1或创建新样式并添加BasedOn Calender

,而不是从generic.xaml中删除样式。

编辑为大卫的回答添加更多信息,让人们看看路上的人

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

这就是你在风格中所需要的一切。 BasedOn将负责复制默认样式中的所有内容,它还将处理不同的主题。如果您从日历的默认主题中复制样式,您将打破所有主题的外观,除了您复制“默认”样式的主题。

答案 1 :(得分:1)

我找到了答案 - 感谢NVM的所有帮助!这通常适用于控件,但它特别适用于Calendar控件。如果要仅修改控件的一部分,则不必包含所有组成控件模板。

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

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

  • 然后,为了开始使用CalendarDayButton,我添加了一个属性设置器,将我的主日历样式的CalendarDayButtonStyle属性指向我的自定义CalendarDayButton样式。

以下是我的Generic.xaml文件中的主要日历样式声明最终看起来像:

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

主日历样式的其余部分未更改 - 它是默认样式的副本。

顺便说一句,CalendarDayButton样式定义必须出现在Generic.xaml中的主日历样式定义之前,否则主日历样式将无法找到它。

我写了一篇名为Extending the WPF Calendar Control的代码项目文章。它介绍了扩展复杂控件(如WPF日历)所涉及的步骤。希望它能帮助那些正在努力解决同样问题的人。

答案 2 :(得分:0)

顺便说一句,我已经发现了Style.BasedOn属性,它可以让你从现有的样式派生出一种样式,而不必重复基本样式。有good blog post on it here