question

Michael-4830 avatar image
Michael-4830 asked ·

WPF: When is data binding applied?

Hallo,

i stuck at a behaviour i can't explain nor find any help in the documentation or various forums.

The following code is needed to explain my problem/ to ask my question. A simple WPF (VB.Net) app that has an combo box (BindingBox) that binds to a List (BindingData):


 Imports System.ComponentModel
    
 Class MainWindow
     Implements INotifyPropertyChanged
    
     Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
     Protected Shadows Sub OnPropertyChanged(ByVal name As String)
         RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
     End Sub
    
     Dim _BindingData As New List(Of String)
    
     Public Property BindingData As List(Of String)
         Get
             Return _BindingData
         End Get
         Set(ByVal value As List(Of String))
             _BindingData = value
             OnPropertyChanged("BindingData")
         End Set
     End Property
    
     Sub New()
         InitializeComponent()
    
         DataContext = Me
         BindingBox.ItemsSource = BindingData
    
         BindingData.Add("Data 1")
         BindingData.Add("Data 2")
     End Sub
    
 End Class


I added the binding to the code-behind, so i do not have to post the xaml. The behaviour is the same also if i establish the binding in the xaml.

Now to my problem/question.
The combo box BindingBox should only be updated if a new list is assigned to BindingData (source of the binding). But in this example BindingBox is also updated after i assigned BindingData to ItemsSource and added items to BindingData afterwards.

After the ui is fully loaded the combo box BindingBox is only updated if a new list is assinged to BindingData and not if items are added or removed (e.g. during a button click). Like it is described in the documentation.

So why is the behaviour different during the initialization? Why are the items displayed in the combo box after the assignment to ItemsSource? I assume that it has something to do with the initialization and loading of the ui and all its element.


I got the advice to post it in MS Q&A (here ist the original post: https://social.msdn.microsoft.com/Forums/vstudio/en-US/9352c02c-2711-4822-a7cd-77c3aaf1c56a/wpf-when-is-data-binding-applied?forum=vbgeneral)

windows-wpf
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

PeterFleischer-3316 avatar image
PeterFleischer-3316 answered ·

Hi, use ObservableCollection instead of List. You can simplified your code like this:

 <Window x:Class="MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:WpfApp1"
         mc:Ignorable="d"
         Title="MainWindow" Height="450" Width="800">
   <StackPanel>
     <Button Content="new row" Click="Button_Click"/>
     <ComboBox ItemsSource="{Binding BindingData}"/>
   </StackPanel>
 </Window>



 Imports System.Collections.ObjectModel
    
 Class MainWindow
    
   Public Property BindingData As New ObservableCollection(Of String)
    
   Sub New()
     InitializeComponent()
    
     DataContext = Me
    
     BindingData.Add("Data 1")
     BindingData.Add("Data 2")
   End Sub
    
   Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
     BindingData.Add("new row")
   End Sub
    
 End Class

5 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi PeterFleischer-3316,

thank you for your answer, i know the use of ObservableCollection but it does not answer my question.

I do not understand why the combo box updates his content if a new element is added to the binded List(of String) - BindingData after it was assigned to the combobox ItemsSource. This happens only before the ui/window is shown, maybe it has something to do with that?

0 Votes 0 · ·

Hi Michael, lhe List class implements no INotifyCollectionChanged, no INotifyPropertyChanged. This means that changes in the list are not signaled to the UI (new, deleted elements). The UI is only updated if a new reference to another instance is assigned to the data source.

0 Votes 0 · ·
Michael-4830 avatar image Michael-4830 PeterFleischer-3316 ·

Hi,

yes i know.

But during the start up of my example (New) i bind an empty list to the combo box:
BindingBox.ItemsSource = BindingData

Afterwards i added some items to the list and after the ui is loaded the combo box contains the items added to the list, but the combo box should be empty. And as you wrote, this should not happen, because the combo box should be only updated if a new instance is assigned.

Maybe it has something to do with the processing of the ui, but why are "Data 1" and "Data 2" in the combo box?

0 Votes 0 · ·
Show more comments
Michael-4830 avatar image
Michael-4830 answered ·

Hi PeterFleischer-3316,

thank you for your answer, i know the use of ObservableCollection but it does not answer my question.

I do not understand why the combo box updates his content if a new element is added to the binded List(of String) - BindingData after it was assigned to the combobox ItemsSource. This happens only before the ui/window is shown, maybe it has something to do with that?

2 comments Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Michael, try this demo code:. Assigning new Instance refresh UI.

 Class MainWindow
    
   Public Property BindingData As New List(Of String)
    
   Sub New()
     InitializeComponent()
    
     DataContext = Me
     BindingBox.ItemsSource = BindingData
    
     BindingData.Add("Data 1")
     BindingData.Add("Data 2")
   End Sub
    
   Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
     BindingData = New List(Of String)
     BindingData.Add("Data 1a")
     BindingData.Add("Data 2a")
     BindingBox.ItemsSource = BindingData
   End Sub
    
 End Class
0 Votes 0 · ·
Michael-4830 avatar image Michael-4830 PeterFleischer-3316 ·

Hi,

yes i know. I wrote a comment in your previouse post. (Sorry for the double post)

0 Votes 0 · ·