【问题标题】:Getting started with a derived custom control?开始使用派生的自定义控件?
【发布时间】:2010-08-19 18:51:52
【问题描述】:

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

  • 我在 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 项目的引用。

【问题讨论】:

  • 通过我实际上从您删除的问题中下载了 FSCalender 项目,虽然我没有 VS2010,但我确实设法在设计器中看到了控件,所以您所拥有的是正确的,它可能是正确构建它的问题。
  • 谢谢——我删除了之前的问题,因为它很长而且很复杂。这是一个更简单的版本。

标签: wpf custom-controls


【解决方案1】:

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

->这一行的意思是 CustomControl1 在 Generic.xaml 中定义了其默认样式

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

-> 这样做是为了移除 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 将负责复制默认样式中的所有内容并且它还将负责不同的主题。如果您从日历的默认主题复制样式,您将破坏所有主题的外观,除了您复制“默认”样式的主题。

【讨论】:

  • 谢谢--日历仍然没有出现。如果我只修改 CalendarDayButton,是否必须在我的 Generic.xaml 中包含所有日历控件模板? Michael Detras 在 EggheadCafe (eggheadcafe.com/tutorials/aspnet/…) 上的自定义控件似乎只包含他修改的控件模板。
  • 糟糕——再看一遍,Detras 包含所有模板。我想我有我的答案。
  • 我认为创建一个空样式并添加 BasedOn Calender 会更好。然后,即使当前操作系统主题改变了所有其他控件的外观,您也不会被日历的相同外观所困。仅当您确实需要为控件更改完全不同的布局时,才应更改新样式中的 ControlTemplate。如果您确实更改了样式中的 ControlTemplate,请记住,我认为最佳做法是您的应用支持的所有主题都有样式(至少阅读与 WPF 捆绑的主题)
  • 有时这只是很多工作,所以我要做的是从硬编码颜色等的样式中删除所有内容,只保留那些我可以参考一些标准颜色等的东西。希望这会有所帮助
【解决方案2】:

我找到了答案——感谢 NVM 的所有帮助!这通常适用于控件,但它特别适用于 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 日历)所涉及的步骤。希望它能帮助其他正在努力解决同样问题的人。

【讨论】:

    【解决方案3】:

    顺便说一句,我后来发现了 Style.BasedOn 属性,它可以让您从现有样式中派生样式,而无需重复基本样式。有一个good blog post on it here

    【讨论】:

      猜你喜欢
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 2012-08-17
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      相关资源
      最近更新 更多