如何在WPF中进行自定义控件

时间:2014-11-07 10:55:22

标签: c# wpf custom-controls

在winforms中有2个模板:UserControl允许复合控件(现有控件组)重用它并使用它标准化操作,CustomControl是一个完全自定义控件(通常手动渲染,执行不同于标准控件等),允许覆盖并提供对protected事物的访问。

在wpf中我只找到UserControl模板(使用VS的快递版)。

要创建自定义MyControl,我正在执行以下操作:

  • 根据Control / ContentControl;
  • 创建普通课程
  • 使用包含控件模板的Style创建资源字典(可能只有ControlTemplate,样式更好,因为可以包含其他属性setter)

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:MySolution">
    <Style x:Key="MyControl" TargetType="local:MyControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:MyControl">
                    <Grid x:Name="PART_Grid">
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
  • 绑定在一起就像这样

public class MyControl : Control
{
    public MyControl()
    {
        var dictionary = new ResourceDictionary();
        dictionary.Source = new Uri("/MySolution;component/MyControl.xaml", UriKind.Relative);
        Style = dictionary["MyControl"] as Style;
        Loaded += MyControl_Loaded;
    }
}
  • 在模板
  • 中定义 lazy 部件访问器

private Grid _partGrid;
private Grid PartGrid
{
    get
    {
        if (_partGrid == null)
            _partGrid = (Grid)Template.FindName("PART_Grid", this);
        return _partGrid;
    }
}

它有效,但我不确定它是否是最佳方式:

  • .cs.xaml是单独的文件(不是一个实体,如wpf UserControl);
  • 移动xaml(例如,在Controls文件夹内)时,必须调整构造函数代码;
  • 部件访问器在构造函数中不可用(模板尚未加载)。

我的问题:是否有更好的方法来使用模板进行自定义控制?更舒适,更自动,带有自动零件访问器等。


这是我的wpf模板

1 个答案:

答案 0 :(得分:0)

最好使用CustomControl VS模板,不确定为什么没有看到它,可能是因为您使用的是Express版本。该模板为您生成Generic.xaml文件,您可以在其中定义styles / controltemplate。此外,您将拥有.cs和控件的c#定义。

要获取控件的不同部分,建议的方法是使用GetTemplateChild方法并传递Part_Name,通常这样做会覆盖OnApplyTemplate()方法。

 public override void OnApplyTemplate()
  {
    base.OnApplyTemplate();

    ActionBtn = GetTemplateChild(BtnPartName) as ButtonBase;
    ContentPopup = GetTemplateChild(PopupPartName) as Popup;
  }

请查看this post以查看具有该实施细节的示例。