简体   繁体   中英

How to make custom control in WPF

In winforms there were 2 templates: UserControl allows to make composite control (group of existing controls) to reuse it and standardize operations with it, CustomControl was a fully custom control (often rendered manually, performing differently than standard controls, etc), allowing overriding and provides access to protected things.

In wpf I only found UserControl template (using express edition of VS).

To create custom MyControl I am doing following:

  • create normal class, based on Control / ContentControl ;
  • create resource dictionary with Style containing control template (could be only ControlTemplate , style is better, because can contain other properties 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>
  • bind them together like this

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;
    }
}
  • define lazy parts accessors in template

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

It works, but I am not sure if its the most optimal way:

  • .cs and .xaml are separate files (not one entity as in case of wpf UserControl );
  • when moving xaml (to example, inside Controls folder) constructor code has to be adjusted;
  • parts accessor are not available in constructor (template is yet not loaded).

My question: is there better way to make custom control with template? More comfortable, automatic, with automatic parts accessors, etc.


Here are my wpf templates

It is better if you use the CustomControl VS template, not sure why you don't see it, maybe because you are using the Express version. That template generates a Generic.xaml file for you, there you define the styles/controltemplate. Also you will have the .cs with the c# definition of your control.

To get the diferent parts of your control, the recommended way is using the GetTemplateChild mehtod and pass the Part_Name and you normally do that overriding the OnApplyTemplate() method.

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

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

Take a look to this post to check a sample with the details of that implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM