0
votes

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

1
There is a custom control template. Also a template for control library. Dunno about Express but kinda expect it to be there.Johan Larsson
@JohanLarsson, see edit, I see here on screenshot there is Templated Control, but I don't have it. There is no online template with such name either. Does my question become "how to get templated control for express edition"? Does it solves issues I listed? Also, you say "control library", I've only "class library" (as a new project) does it matter?Sinatr
@Sinatr it might indeed be express related. i used to test things in express too, which lacked some pretty vital templates. might be the case here too.Dbl

1 Answers

0
votes

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.