Question

I have the following code, but the problem is that PropertyChanged is always null when I try to fire it. Why is that, and how could I get around this?

Creating the ListView programmatically and adding a binding to it:

            ListView listView = new ListView();
            listView.Height = 203;
            listView.Width = 501;
            listView.Margin = new Thickness(0, 0, 0, 0);
            Grid.SetRow(listView, 1);
            Grid.SetColumn(listView, 0);
            mainGrid.Children.Add(listView);
            GridView myGridView = new GridView();
            myGridView.AllowsColumnReorder = true;
            System.Windows.Controls.GridViewColumn gvc1 = new System.Windows.Controls.GridViewColumn();
            gvc1.DisplayMemberBinding = new Binding("Date");
            gvc1.Header = "Date";
            gvc1.Width = 100;
            myGridView.Columns.Add(gvc1);
            System.Windows.Controls.GridViewColumn gvc2 = new System.Windows.Controls.GridViewColumn();
            gvc2.DisplayMemberBinding = new Binding("Application");
            gvc2.Header = "Application";
            gvc2.Width = 100;
            myGridView.Columns.Add(gvc2);
            System.Windows.Controls.GridViewColumn gvc3 = new System.Windows.Controls.GridViewColumn();
            gvc3.DisplayMemberBinding = new Binding("Message");
            gvc3.Header = "Message";
            gvc3.Width = 100;
            myGridView.Columns.Add(gvc3);
            listView.View = myGridView;
            // Create a new binding object and set the binding of this list view to it.
            //rows = new ObservableCollection<Row>();
            rows = new Rows();
            // Create a background worker to update the rows every second.
            BackgroundWorker bgworker = new BackgroundWorker();
            bgworker.WorkerReportsProgress = true;
            bgworker.DoWork += (doWorkSender, doWorkEventArguments) => {
                for (int i = 0; i < 1000000; i++) {
                    Thread.Sleep(1000);
                    bgworker.ReportProgress(i);
                }
                doWorkEventArguments.Result = null;
            };
            bgworker.ProgressChanged += (progressChangedSender, progressChangedEventArguments) => {
                rows.Add(new Row { Date = DateTime.Now.ToString(), Application = "Application", Message = "This is a sample message." });
            };
            bgworker.RunWorkerAsync();
            listView.DataContext = rows;
            Binding myBinding = new Binding();
            myBinding.Source = rows;
            listView.SetBinding(ItemsControl.ItemsSourceProperty, myBinding);

The Row and Rows classes:

    public class Row {
        public string Date { set; get; }
        public string Application { set; get; }
        public string Message { set; get; }
    }

    public class Rows : IEnumerable<Row>, INotifyPropertyChanged {
        public List<Row> rowList { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        public Rows() {
            rowList = new List<Row>();
        }

        public void Add(Row item) {
            rowList.Add(item);
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs("rowList"));
            }
            else {
                Console.WriteLine("PropertyChanged is null.");
            }
        }

        public IEnumerator<Row> GetEnumerator() {
            return rowList.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }

    }

The rows object is declared as a Rows type:

Rows rows;
Was it helpful?

Solution

You need to implement INotifyCollectionChanged in your class Rows and fire CollectionChanged instead of PropertyChanged. In fact, you don't need to implement INotifyPropertyChanged since there is no bindings to properties of Rows.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top