In the development of XAML (WPF/UWP) applications,

sometimes needs to create a custom control (Custom Control) to meet the actual needs. In custom controls, we usually use a number of native controls (such as Button, TextBox, etc.) to assist in the function of a custom control.

custom controls are not like user controls (User Control), using Code-Behind (UI and logic together) technology. Instead, it decouple the two by separating the UI from the logic. Therefore, to create a custom control will produce two documents, one is Generic.xaml, the definition of template and style in it; the other is < ControlName>.Cs, which stored inside the logic, as shown below:


in this case, if you want to get in the code definition control template, it is not so easy to Code-Behind, and with the help of OnApplyTemplate and GetTemplateChild of the two methods. They are as follows: the significance of

OnApplyTemplate: in a custom control, usually to override this method, when the base call ApplyTemplate () method to construct the visual tree, it will be called

GetTemplateChild:; get the name specified as the tree elements defined in ControlTemplate

; therefore, if we define a called the PART_ViewButton button in the template, then we can get it, and registered in response to the incident for it:

 public override void (OnApplyTemplate) {base.OnApplyTemplate (Button); btnView = GetTemplateChild ("PART_ViewButton") as Button; if (btnView! = null) {btnView.Click}} = BtnView_Click; private void BtnView_Click (object sender, RoutedEventArgs E) {/ / Here we write the response logic}

. When we (or others) want to use this control, by setting templates to it, usually the default template, the OnApplyTemplate method will be executed. It doesn't seem to be a problem. However, it can actually cause a problem that sounds very serious: the memory leak (Memory Leak).

is memory leak.

has many kinds of memory leaks. Generally speaking, it means that some types of resources are no longer used, but they still occupy memory. In other words, it "leaks" out of the managed memory area. If there are many memory leaks in the program, it will occupy a lot of memory and eventually lead to the memory being exhausted.

in C#, the common memory leaks are:


event is not removed; no destruction of unmanaged resources (such as databases, file streams, etc.);

for the above two kinds of circumstances, their solution is also very simple, namely: to register the event (i.e. remove anti call the Dispose method and event monitoring) (if not, must implement the IDisposable interface, and in which the destruction of unmanaged resources).

is well understood for second situations. For the first case, the question is, why did not remove event listener and cause memory leak? This is because the source of the event is longer than the event monitor's life cycle. See the

 ObjectA Code: 

objA = new (ObjectA); ObjectB objB = new (ObjectB); objA.Event = objB.EventHanlder;

defined in the

ObjectA Event event, we register an event handler for it (EventHanlder method objB); therefore, a reference to the objA event source event listener object objB there.

, if objB is no longer in use, we will destroy it, but because objA quoted it, it will not be destroyed or recycled. It will not be destroyed until objA destroys. So the object that needs to be destroyed, but because there is a reference to it by other objects, results in a memory leak.

back to how to solve the problem of custom controls, because our custom controls, may be rewritten rewriting style or template, this will make the OnApplyTemplate method in the custom control life cycle is executed many times. Therefore, we need to control events that are obtained by GetTemplateChild and add event processing, such as btnView control in the above code. Because these are controls (elements) in the previous template. After anti registration, there is no reference relationship between the original control and the event listener (custom control itself), thereby avoiding the problem of memory leakage.

according to our thoughts, before the code refactoring as follows:

 private Button btnView public override void = null; OnApplyTemplate (base.OnApplyTemplate) {(); / / the first anti registered event if (btnView! = null) {btnView.Click} - = BtnView_Click; btnView = GetTemplateChild ("PART_ViewButton") as Button; if (btnView! = null) {btnView.Click}} = BtnView_Click; private void BtnView_Click (object sender, RoutedEventArgs E) {/ /}

here to write the response logic so that to solve the problem of the start of. However, next, we need to do a little bit of adjustment.

reconstruction further imagine, if our custom controls, there are a number of similar such as the btnView control, we will copy the above code several times in the OnApplyTemplate method, which leads to increasing the complexity of the OnApplyTemplate method, and the readability of the code variation. In order to improve this,

encapsulates each control and its event registration and anti registration.


 protected const Code: string PART_ViewButton = NAMEOF (PART_ViewButton); private Button btnView = null public; Button ViewButton {get {return} set {btnView; / / the first anti registered event if (btnView! = null) {btnView.Click} - = BtnView_Click; btnView = value; if (btnView! = null) {btnView.Click}}} = BtnView_Click; public override void (OnApplyTemplate) {base.OnApplyTemplate (ViewButton) = GetTemplateChild (PART_ViewButton); as Button; private void BtnView_Click} (object sender, RoutedEventArgs E) {/ / write response here }

for the final code, here a few more points:

1. in the OnApplyTemplate method, a proposal to start calling base.OnApplyTemplate (

2.); in control for anti registered event, or a registered event, to determine whether the control is empty, this is because there may be specified in the TemplatePart property to the name of the control did not follow the user template

3. will override; the name of the control statement is a constant string of spelling mistakes can be avoided;

"summary is discussed in this paper to create custom controls in WPF or UWP, may have a memory leak the problem; this is mainly due to the controls in the event no template Caused by anti registration. We have not only analyzed the reasons for it, but also gave the best practice for this situation.

although in general, this problem will not cause a greater impact, but if we can pay attention on the details, this can not only improve the code quality and performance of our programs, we can to deal with similar problems in design, provide ideas and experience necessary.

above, the best practice method of event handling in XAML: custom controls is all the contents that Xiaobian shared to you. I hope to give you a reference, and I hope you will support the script home more.

This concludes the body part

This paper fixed link: | Script Home | +Copy Link

Article reprint please specify:The best practice method for event handling in XAML: custom controls | Script Home

You may also be interested in these articles!