UserControl Class

Updated: February 2009

Provides a simple way to create a control.

Namespace:  System.Windows.Controls
Assembly:  PresentationFramework (in PresentationFramework.dll)
XMLNS for XAML: http://schemas.microsoft.com/winfx/2006/xaml/presentation, http://schemas.microsoft.com/netfx/2007/xaml/presentation

'Declaration
Public Class UserControl _
	Inherits ContentControl
'Usage
Dim instance As UserControl
<UserControl>
  Content
</UserControl>

Controls in Windows Presentation Foundation (WPF) support rich content, styles, triggers, and templates. In many cases, these features allow you to create custom and consistent experiences without having to create a new control. For more information, see Styling and Templating.

If you do need to create a new control, the simplest way is to create a class that derives from UserControl. Before you do so, consider that your control will not support templates and therefore will not support complex customization. However, deriving from UserControl is a suitable model if you want to build your control by adding existing elements to it, similar to how you build an application, and if you do not need to support complex customization. (If you want to use templates with your control, derive from Control instead.) For more information about the different models for authoring controls, see Control Authoring Overview.

Content Model: UserControl is a ContentControl. Its content property is Content. For more information on the content model for UserControl, see Controls Content Model Overview.

Dependency properties for this control might be set by the control’s default style. If a property is set by a default style, the property might change from its default value when the control appears in the application. The default style is determined by which desktop theme is used when the application is running. For more information, see Themes.

The following example shows how to create a simple NumericUpDown UserControl.

<!--XAML for NumericUpDown that inherits from UserControl.-->
<UserControl x:Class="MyUserControl.NumericUpDown"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyUserControl">
    <Grid Margin="3">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Border BorderThickness="1" BorderBrush="Gray" Margin="2" 
                Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Stretch">

            <!--Bind the TextBlock to the Value property-->
            <TextBlock 
                Width="60" TextAlignment="Right" Padding="5"
                Text="{Binding RelativeSource={RelativeSource FindAncestor, 
                               AncestorType={x:Type local:NumericUpDown}}, 
                               Path=Value}"/>

        </Border>

        <RepeatButton Name="upButton" Click="upButton_Click" 
                      Grid.Column="1" Grid.Row="0">Up</RepeatButton>

        <RepeatButton Name="downButton" Click="downButton_Click" 
                      Grid.Column="1" Grid.Row="1">Down</RepeatButton>

    </Grid>
</UserControl>

The following shows the logic of this UserControl:

using System;
using System.Windows;
using System.Windows.Controls;

namespace MyUserControl
{
    public partial class NumericUpDown : System.Windows.Controls.UserControl
    {
        /// <summary> 
        /// Initializes a new instance of the NumericUpDownControl. 
        /// </summary> 
        public NumericUpDown()
        {
            InitializeComponent();

        }

        /// <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);
        }

        /// <summary> 
        /// Identifies the ValueChanged routed event. 
        /// </summary> 
        public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent(
            "ValueChanged", RoutingStrategy.Bubble, 
            typeof(RoutedPropertyChangedEventHandler<decimal>), typeof(NumericUpDown));

        /// <summary> 
        /// Occurs when the Value property changes. 
        /// </summary> 
        public event RoutedPropertyChangedEventHandler<decimal> ValueChanged
        {
            add { AddHandler(ValueChangedEvent, value); }
            remove { RemoveHandler(ValueChangedEvent, value); }
        }

        /// <summary> 
        /// Raises the ValueChanged event. 
        /// </summary> 
        /// <param name="args">Arguments associated with the ValueChanged event.</param>
        protected virtual void OnValueChanged(RoutedPropertyChangedEventArgs<decimal> args)
        {
            RaiseEvent(args);
        }

        private void upButton_Click(object sender, EventArgs e)
        {
            Value++;
        }

        private void downButton_Click(object sender, EventArgs e)
        {
            Value--;
        }

        private const decimal MinValue = 0, MaxValue = 100;
    }
}

For the complete sample, see NumericUpDown UserControl with DependencyProperty and RoutedEvent Sample. For more information, see Control Authoring Overview.

System.Object
  System.Windows.Threading.DispatcherObject
    System.Windows.DependencyObject
      System.Windows.Media.Visual
        System.Windows.UIElement
          System.Windows.FrameworkElement
            System.Windows.Controls.Control
              System.Windows.Controls.ContentControl
                System.Windows.Controls.UserControl

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 7, Windows Vista, Windows XP SP2, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0

Date

History

Reason

February 2009

Described how default styles change dependency properties.

Customer feedback.

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

ADD
Show:
© 2014 Microsoft