WPF Road - User Control vs Custom Control UserControl VS CustomControl)

  • Combine multiple existing controls into a reusable "group".
  • Consists of a XAML file and a code-behind file.
  • Styles and templates cannot be used.
  • Inherited from the UserControl class.

Custom Controls (Extensions)

  • Extend the existing controls, add some new property methods, etc.
  • Includes a code file and a default theme file.
  • Styles and templates are available.
  • A great way to build a library of controls.
=======================================================================

UserControl is mostly a combination of existing controls. The combination is a good combination. I just drag a few controls and put them on the page. For example, I get a TextBox and a button to the inside of the page, and the name is UserControl. For example, in the WPF form, I want to assign a value to the TextBox in this UserControl or get its value. How to get it? I want to click the Button in the UserControl to trigger an event in the WPF form background code file where the UserControl is located (not to mention the MVVM mode), how to trigger it? These two issues are the key issues in creating UserControl.

First question: get or set properties.

Create a wpf user control project, add a Button and TextBox in UserControl1.xaml. User control inherits from UserControl class by default, you can also modify his inherited class. If modified to another class, UserControl will have the corresponding methods and properties of this class. Do not modify it here, keep its default inheritance.

The main task now is to get or set the value of the TextBox inside the form when the user control is placed in the WPF form.

The key step is to add a dependency property to this user control.

For example, I want to add a Text property to this user control, that is, when I put this user control in the WPF window, I want to get or set its Text property.

The code to add this Text dependency property is as follows:

 

So for this user control

public static readonly DependencyProperty TextProperty =
           DependencyProperty.Register("Text", typeof(string),
           typeof(UserControl1),
           new PropertyMetadata("TextBox", new PropertyChangedCallback(OnTextChanged)));
        public string Text
        {
            get { return (string)GetValue(TextProperty); }

            set { SetValue(TextProperty, value); }
        }

        static void OnTextChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            UserControl1 source = (UserControl1)sender;
            source.tb.Text = (string)args.NewValue;
        }

Added a property named Text. If you happen to be doing this or learning this, and you see this article through search, it is estimated that someone will directly look at the above code and realize it, and I am very happy. This is fast, but this is where go fish instead of fish. The main code here is
public static readonly DependencyProperty TextProperty =
           DependencyProperty.Register("Text", typeof(string),
           typeof(UserControl1),
           new PropertyMetadata("TextBox", new PropertyChangedCallback(OnTextChanged)));

Then mainly the DependencyProperty.Register method.

The first parameter is the name of the property you want to add to this user control, that is, what string do you fill in the first parameter in the future, your user control will add a property with this string as the name.

The second parameter refers to the data type corresponding to this property.

The third parameter is the type of the owner of this property.

第四个参数属性改变时触发的回调事件。

这个方法及其参数弄懂后,就很容易来为用户控件增加属性了。

下面第二个大问题,事件传阅。

比如我们想让这个用户控件暴露给窗体一个MyButtonClick事件。代码如下

public static readonly RoutedEvent MyButtonClickEvent =
            EventManager.RegisterRoutedEvent("MyButtonClick", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<object>), typeof(UserControl1));

        public event RoutedPropertyChangedEventHandler<object> MyButtonClick
        {
            add
            {
                this.AddHandler(MyButtonClickEvent, value);
            }

            remove
            {
                this.RemoveHandler(MyButtonClickEvent, value);
            }
        }

        public void OnMyButtonClick(object oldValue, object newValue)
        {
            RoutedPropertyChangedEventArgs<object> arg =
                new RoutedPropertyChangedEventArgs<object>(oldValue, newValue, MyButtonClickEvent);
           
            this.RaiseEvent(arg);
        }

这样通过这两段代码你的用户控件就得到了一个Text属性和一个MyButtonClick方法。

请注意以上两段代码中,特别是第二段注册事件的代码中要特别注意,当你的用户控件继承的基类不同时,注册事件时可能所用的参数和事件的类型会有所不同,比如msdn上有个例子是继承自Button的,其中的事件类型和参数就不同:

public class MyButtonSimple: Button
{
    // Create a custom routed event by first registering a RoutedEventID
    // This event uses the bubbling routing strategy
    public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
        "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));

    // Provide CLR accessors for the event
    public event RoutedEventHandler Tap
    {
            add { AddHandler(TapEvent, value); } 
            remove { RemoveHandler(TapEvent, value); }
    }

    // This method raises the Tap event
    void RaiseTapEvent()
    {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(MyButtonSimple.TapEvent);
            RaiseEvent(newEventArgs);
    }
    // For demonstration purposes we raise the event when the MyButtonSimple is clicked
    protected override void OnClick()
    {
        RaiseTapEvent();
    }

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325852915&siteId=291194637