我正在尝试派生自定义控件,我创建了我认为最简单的派生:
我在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项目的引用。
答案 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。