none
Why Binding never call Converter more than once?

    Question

  • Hello msdn,

           I am facing one problem regarding binding in WPF, that When I used one Converter element in binding of ItemsSource property of a DataGrid, the converter is calling only Once(At the beginning only)

    Why not the Converter method is not calling everytime the Value is changed in the ItemsSource??

    my code is published below.

    Xaml code:

     

    <Window x:Class="ObservableCollectionsRnD.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:my="clr-namespace:ObservableCollectionsRnD"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <my:MyConverter x:Key="MyConverter1" />
        </Window.Resources>
        <Grid>
            <DataGrid AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Margin="0,30,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="503" 
                      ItemsSource="{Binding studentList, Converter={StaticResource MyConverter1}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="194,258,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        </Grid>
    </Window>
    
    

     


    cs Code:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    
    namespace ObservableCollectionsRnD
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public ObservableCollection<Student> studentList { get; set; }
            
            public MainWindow()
            {
                studentList = new ObservableCollection<Student>();
                InitializeComponent();
                studentList.Add(new Student() { RollNo = 1, Name = "Studentttt" });
                this.DataContext = this;
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                studentList.Add(new Student() { RollNo = 1, Name = "Studentttt" });
            }
        }
        /// <summary>
        /// DataClass
        /// </summary>
        public class Student
        {
            public int RollNo { get; set; }
            public string Name { get; set; }
        }
       /// <summary>
       /// Converter Class
       /// </summary>
        public class MyConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                //throw new NotImplementedException();
                if (null != value)
                {
    
                    return value; //  as Student;
                }
    
                return null;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }
    
    


     

    what is wrong in this?

    why not the Converter calling  while the observable collection changing(collection is changing in Button Click Event)?

    Does anybody know the reason?

    if so please let me know what is wrong in this(Binding)?

     

     

    Any help will be appreciated

    Regards

    SalamPV

     


    salampv.07

    • Edited by salam.p.v Friday, January 20, 2012 12:19 PM
    Friday, January 20, 2012 12:17 PM

Answers

  • Hi Salampv.07

    I think I got it

    Change Your datagrid  Xaml As follow

     

    <DataGrid AutoGenerateColumns="True"
                      Height="200" 
                      HorizontalAlignment="Left" Margin="0,30,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="503" 
                      ItemsSource="{Binding studentList, Converter={StaticResource MyConverter1}, Mode=TwoWay, UpdateSourceTrigger=Explicit}"                  />
    

     


    change in Converter

     

     public class MyConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (null != value)
                {
    
                    return value; //  as Student;
                }
    
                return null;
            }
    
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (null != value)
                {
    
                    return value; //  as Student;
                }
    
                return null;
            }
        }
    

     

    change in ButtonClick Event

     

      private void button1_Click(object sender, RoutedEventArgs e)
            {
                studentList.Add(new Student() { RollNo = 1, Name = "Studentttt" });
               dataGrid1.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateSource();
            }
    

    my side it is working

    Thank You

    Mayank

     


    • Edited by Rajpura Mayank Saturday, January 21, 2012 9:49 AM
    • Marked as answer by salam.p.v Saturday, January 21, 2012 11:31 AM
    Saturday, January 21, 2012 9:48 AM

All replies

  • Hi,

     

    Could you please post the xaml showing how this converter is used?

     

    Thanks.

    Friday, January 20, 2012 12:30 PM
  • Hi Pritesh3 

     I've already given the xaml in my post

    FYI:

    <Window x:Class="ObservableCollectionsRnD.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:my="clr-namespace:ObservableCollectionsRnD"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <my:MyConverter x:Key="MyConverter1" />
        </Window.Resources>
        <Grid>
            <DataGrid AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Margin="0,30,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="503" 
                      ItemsSource="{Binding studentList, <strong>Converter={StaticResource MyConverter1},</strong> Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="194,258,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        </Grid>
    </Window>
    
    


    Regards

    salampv


    salampv.07
    Friday, January 20, 2012 12:46 PM
  • Hi,

    Because when you insert a record in observablecollection, it hust add one record in it, but notification can not set to ui.

    So you can test it using INotifyPropertychanged interface.

    Add below code to your window.xaml.cs

     public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            private ObservableCollection<Students> _studentList=new ObservableCollection<Students>();
            public ObservableCollection<Students> studentList
            {
                get { return _studentList; }
                set
                {
                    _studentList = value; // Put debig point here
                    OnPropertyChanged("studentList");
                }
            }
    

    run this when you insert a record in collection, it setter property can not be notified.

    Add below code for constructor and buttonclick

     public Window29()
            {
                
                InitializeComponent();
                _studentList.Add(new Students() { RollNo = 1, Name = "Studentttt" });
                OnPropertyChanged("studentList");
                this.DataContext = this;
             }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                _studentList.Add(new Students() { RollNo = 2, Name = "Studentttt" });
                OnPropertyChanged("studentList");
            }
    


    Thanks,

    Rajnikant

    Friday, January 20, 2012 12:47 PM
  • Thank you Rajnikanth,

    But it have no Impact on calling Converter while each item added to the collection , i mean changes in collection

     

    Regards

    Salam


    salampv.07
    Friday, January 20, 2012 1:05 PM
  • Hi Salampv.07

    I think I got it

    Change Your datagrid  Xaml As follow

     

    <DataGrid AutoGenerateColumns="True"
                      Height="200" 
                      HorizontalAlignment="Left" Margin="0,30,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="503" 
                      ItemsSource="{Binding studentList, Converter={StaticResource MyConverter1}, Mode=TwoWay, UpdateSourceTrigger=Explicit}"                  />
    

     


    change in Converter

     

     public class MyConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (null != value)
                {
    
                    return value; //  as Student;
                }
    
                return null;
            }
    
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                if (null != value)
                {
    
                    return value; //  as Student;
                }
    
                return null;
            }
        }
    

     

    change in ButtonClick Event

     

      private void button1_Click(object sender, RoutedEventArgs e)
            {
                studentList.Add(new Student() { RollNo = 1, Name = "Studentttt" });
               dataGrid1.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateSource();
            }
    

    my side it is working

    Thank You

    Mayank

     


    • Edited by Rajpura Mayank Saturday, January 21, 2012 9:49 AM
    • Marked as answer by salam.p.v Saturday, January 21, 2012 11:31 AM
    Saturday, January 21, 2012 9:48 AM
  • Thank you Myank, Thank you very much My Side also its working fine. if further requirement I will post on the same forum. Regards Muhammed Abdussalam
    salampv.07
    Saturday, January 21, 2012 11:33 AM