Summary: In some cases, we do need to create new controls. At this point, it is important to understand how the different WPF controls are created. WPF provides three methods for creating controls, each of which provides a different degree of flexibility.

WPF controls can reduce the need to create new controls through mechanisms such as data plates, styles, control templates, and triggers. However, in some cases, we do need to create new controls. At this point, it is important to understand how the different WPF controls are created. WPF provides three methods for creating controls, each of which provides a different degree of flexibility, described below.

1 Created based on UserControl

One of the easiest ways to create a control is to inherit from the UserControl class. At this point, we can add existing components from WPF to the UserControl canvas and name the components so that component access and event handlers can be used in the background. UserControl can take advantage of rich content, styles, and triggers. However, controls that inherit from UserControl will not be able to customize the UI appearance using DataTemplate or ControlTemplate.

2 Based on Control

Methods to create custom controls based on the Control class, using templates to define the look and feel of the UI. And you can separate the back-end logic from the front-end style presentation. In addition, custom controls created in this way also support the use of commands and bindings to perform related actions to achieve event-like effects. Finally, controls can redefine the ControlTemplate and DataTemplate to customize the UI appearance. Control supports different themes.

3 Create based on a FrameworkElement

In general, custom controls created based on UserControl or Control will do the job, but there are special cases where a simple combination of elements will not satisfy the UI appearance requirements of a custom Control. At this point, creating custom controls based on a FrameworkElement is a good choice.

Create controls based on a FrameworkElement. On the one hand, you can rewrite the OnRender method to draw the UI directly. On the other hand, you can visualize the appearance of a written component by customizing the composition of elements.

4 Dependent Properties

WPF can change the appearance and behavior of a control by setting its properties. The dependency properties allow custom controls to do the following:

  • Set this property in the style.
  • Bind this property to the data source.
  • Use a dynamic resource as the value for this property.
  • Animate the property.

If the control has a property that supports any of the above capabilities, implement that property as a dependent property. The following is an example of Microsoft official documents:

/// <summary>
/// Identifies the Value dependency property.
/// </summary>
public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register(
        "Value", typeof(decimal), typeof(NumericUpDown),
        new FrameworkPropertyMetadata(MinValue, new PropertyChangedCallback(OnValueChanged),
                                      new CoerceValueCallback(CoerceValue)));

/// <summary>
/// Gets or sets the value assigned to the control.
/// </summary>
public decimal Value
{
    get { return (decimal)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

private static object CoerceValue(DependencyObject element, object value)
{
    decimal newValue = (decimal)value;
    NumericUpDown control = (NumericUpDown)element;

    newValue = Math.Max(MinValue, Math.Min(MaxValue, newValue));

    return newValue;
}

private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    NumericUpDown control = (NumericUpDown)obj;         

    RoutedPropertyChangedEventArgs<decimal> e = new RoutedPropertyChangedEventArgs<decimal>(
        (decimal)args.OldValue, (decimal)args.NewValue, ValueChangedEvent);
    control.OnValueChanged(e);
}
Copy the code

This sample code is from the official website docs.microsoft.com/zh-cn/dotne… , which defines a dependency property called ValueProperty (DependencyProperty), by calling the DependencyProperty. Register registered name of the attribute Value to the property system, which contains three core information:

  • The name of the property Value
  • Property of type Decimal
  • The type that has the attribute NumericUpDown
  • Attribute metadata information (FrameworkPropertyMetadata)

The metadata for the property contains the default values for the property, CoerceValueCallback and PropertyChangedCallback. CoerceValue ensures that Value is greater than or equal to MinValue and less than or equal to MaxValue. PropertyChangedCallback, moreover, the callback method for OnValueChanged, to deal with the related attribute value change logic, behind by RoutedPropertyChangedEventArgs created a routing, This is triggered via control.onValuechanged (e).

The original link

This article is the original content of Aliyun and shall not be reproduced without permission.