commandhandlers stacking up inside itemscontrol after clear / re add
-
Thursday, February 25, 2010 9:01 PM
Hello all, I am having a little problemI have an itemscontrol bound to an ObservableCollection. In the itemscontrol's datatemplate, I bind a DatePickers SelectedDateChanged event to a command in the view model.The items in the itemscontrol get a certain look after what values their properties are, so when the properties of an items ObservableCollection are changed, I "refresh" the itemscontrol datatemplate by simply clearing the observablecollection and re adding the elements.The problem I have is that for each time I clear/readd the items, the command in my view model is called n-more times, where n is the number of times I "refresh".Obviously there are some objects / handlers left or stacking up.For binding to the SelectedDateChange command i use acb, http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/Can post some code tomorrow if needed. ThanksEdit<Window x:Class="EventBugging.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Eventing="clr-namespace:KrediNor.Communicare.Common.Eventing" xmlns:cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation" xmlns:Controls1="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" Title="Window1" Height="800" Width="500"> <Grid x:Name="MyGrid"> <StackPanel> <Button Content="Refresh" cal:Click.Command="{Binding RefreshCommand}" /> <ItemsControl ItemsSource="{Binding People}" > <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Controls1:DatePicker SelectedDate="{Binding Time, Mode=TwoWay}" > <Eventing:CommandBehaviorCollection.Behaviors> <Eventing:BehaviorBinding Event="SelectedDateChanged" Command="{Binding ElementName=MyGrid, Path=DataContext.DateChanged}" CommandParameter="{Binding }" /> </Eventing:CommandBehaviorCollection.Behaviors> </Controls1:DatePicker> <TextBlock Text="{Binding Name}" /> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <TextBox Height="500" Text="{Binding Logg, Mode=TwoWay}" /> </StackPanel> </Grid> </Window>namespace EventBugging { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using Microsoft.Practices.Composite.Presentation.Commands; /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : INotifyPropertyChanged { public DelegateCommand<object> DateChanged { get; set; } public DelegateCommand<object> RefreshCommand { get; set; } List<Person> _archive = new List<Person>(); private ObservableCollection<Person> _people; public ObservableCollection<Person> People { get { return _people; } set { _people = value; NotifyPropertyChanged("People"); } } private string _logg; public string Logg { get { return _logg; } set { _logg = value; NotifyPropertyChanged("Logg"); } } public Window1() { InitializeComponent(); _archive = GetListOfPersons(); _people = new ObservableCollection<Person>(_archive); DataContext = this; DateChanged = new DelegateCommand<object>(DateChangedCommandHandler); RefreshCommand = new DelegateCommand<object>(RefreshCommandHandler); } private void RefreshCommandHandler(object obj) { People = new ObservableCollection<Person>(_archive); } private void DateChangedCommandHandler(object obj) { var person = obj as Person; Logg += person.Name + "\n"; RefreshCommandHandler(null); } static List<Person> GetListOfPersons() { var people = new List<Person>(); people.Add(new Person("Luke", DateTime.Now)); people.Add(new Person("Joe", DateTime.Now)); people.Add(new Person("Williak", DateTime.Now)); people.Add(new Person("Jack", DateTime.Now)); people.Add(new Person("Averell", DateTime.Now)); return people; } public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { if(PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } public class Person { public string Name { get; set; } private DateTime _time; public DateTime Time { get { return _time; } set { _time = value; } } public Person(string name, DateTime time) { Name = name; Time = time; } } }- Edited by BBuddy Friday, February 26, 2010 9:15 AM added code sample
All Replies
-
Tuesday, March 02, 2010 12:32 PMModerator
Hi BBuddy,
I think the reason cause this problem is that you refresh the items with the reference itself. When you refresh the items with the following sentence:
People = new ObservableCollection<Person>(_archive);
it will get and set the property Time of people, while you have defined behaviors for it in XAML.If you change the way to refresh as follows, the problem will be solved:
Code-behind(Modified part)
private void RefreshCommandHandler(object obj)
{
People = new ObservableCollection<Person>(RefreshPeople());
}
private List<Person> RefreshPeople(){
var people = new List<Person>();
people.Add(new Person(_people[0].Name, _people[0].Time));
people.Add(new Person(_people[1].Name, _people[1].Time));
people.Add(new Person(_people[2].Name, _people[2].Time));
people.Add(new Person(_people[3].Name, _people[3].Time));
people.Add(new Person(_people[4].Name, _people[4].Time));
return people;
}
Hope this helps.
Best regards,
Linda Liu
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Marked As Answer by Linda LiuModerator Thursday, March 04, 2010 3:19 AM

