Dear gurus, please explain the bindings. In educational articles "for dummies", leak issues are not considered at all, and an independent search for information in parts led to my confusion. What I dug:
To combat memory leaks in WPF, you need to bind to objects that implement INotifyCollectionChanged . Ok, in the case of collections, everything is clear. We bind through ObservableCollection .

But what about simple data types?

Suppose we have a simple page on which there is a text field where the user enters his name. To work with this name, we will bind it to the name field.

View:

 <TextBlock Text="Ваше имя:"/> <TextBox Text="{Binding name}"/> 

ViewModel:

 public string name {get; set;} ... this.DataContext = this; this.InitializeComponent(); 

According to this page, to deal with a leak, you must either implement INotifyPropertyChanged on the source object, or set the DependencyProperty property. But nowhere can I find a simple example of how to do it correctly.


Here , in the last paragraph, it is generally written:

If you use .NET Framework 4.5, then you will not have a memory leak

So how to implement data binding correctly ?

  • In practical situations, such a leak occurs very rarely, for example, I have never had one. - VladD
  • @VladD What does it depend on? Why does someone arise, and someone does not? And how to do the right thing? 1. To score and hope that the leak will never occur? 2. INotifyPropertyChanged with these INotifyPropertyChanged and DependencyProperty and use them always in such cases? - user200141
  • Wrote the answer. In any case, it is necessary to deal with INPC and DP! - VladD

1 answer 1

In the document to which you refer, the following is written:

This issue occurs if the following conditions are true:

  • A data-binding path refers to property P of object X
  • Object X contains the data linking operation.
  • Property Property is accessed through a PropertyDescriptor object or PropertyInfo object.

Of these conditions, the second is unusual: “The X ray data linking operation”.

If you program using MVVM, your X object is most likely a VM object, and the target element of the binding is a View object. In a normal situation, VM objects do not have the right to know about View, and thus should not contain direct or indirect references to it.

This means that a problem can arise only if your View-object refers to another View-object. But the properties of UI objects are usually DependencyProperty , so this case is also not the case in the vast majority of cases.

What do we have to do?

  1. If you Binding UI object to another property of the UI object, it makes sense to pay attention to whether or not you are binding, DependencyProperty . In most cases, it will be so.
  2. If, however, it turns out that you need to bind the property of one UI object to another property that is not a DependencyProperty (for example, as in the example from the article you quoted:

     <StackPanel Name="MyStackPanel"> <TextBlock Text="{Binding ElementName=MyStackPanel, Path=Children.Count}" /> </StackPanel> 

    in this example, memory leak occurs in VS 2015), you need to change the Binding to OneTime : in this case, you still do not receive notifications about the property change ( INotifyPropertyChanged not implemented, and the property is not DependencyProperty ).

  3. A more pragmatic approach - do not mess with each binding, test your application using the memory profiler, and if you find a memory leak described in the article, fix it as indicated in item 2.
  • Thanks for the detailed answer. After reading several times, I began to understand. For complete clarity, I lack understanding: 1. Do I understand correctly that in the context of your answer View-объект == UI-объект , and all of them together are any FrameworkElement ? 2. It turns out that the correct answer to the question "Will there be a memory leak?" with the code in my question - "No"? - user200141
  • @ user200141: (1) Yes, but not necessarily FrameworkElement : for example, StackPanel.Children may be just an IList or something like that. This refers to UI-layer objects. (2) If you do not have references from DataContext but back to the UI, that is correct. - VladD
  • Forgive the lack of my knowledge, I just can’t understand / google the expression (2). I realized that if I tie exactly the way I wrote in the question, then everything is OK. If I refer from a VM through x: Name something like this: MyTextBox.Text = someDefaultTextVariable , then the memory will MyTextBox.Text = someDefaultTextVariable ? - user200141
  • @ user200141: Well, the code-behind of the control or the window is not a VM, it’s the same View-layer. What you are going to do Binding is an object from another layer, which should not know anything about View. - VladD
  • This is a twist :) I still see me learning and studying. Thanks for the explanation. At least the answer to my question is clear to me now. - user200141