In the release 2013Q1sp1, I have a serious binding exception when code change a binding property value. it because I send property changed event in a back work thread, and control may not handle invoke requirement and correct work in cross thread status. In older version ,everything is ok, so in 2013Q1sp1 must do some changes.
I use a demo project and change some code to show this issue, the project can work well in 2013Q1, but have exception in 2013Q1sp1
MainWindow.xaml:
MainWindow.xaml.cs
I use a demo project and change some code to show this issue, the project can work well in 2013Q1, but have exception in 2013Q1sp1
MainWindow.xaml:
<Window x:Class="RadControlsWpfApp17.MainWindow" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition /> </Grid.RowDefinitions> <telerik:RadToolBar> <Button Command="{Binding ChangeCommand}" Content="Change Begin" Height="24" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Top" Width="81" /> </telerik:RadToolBar> <telerik:RadGridView ItemsSource="{Binding Data}" GroupRenderMode="Flat" AutoGenerateColumns="False" CanUserFreezeColumns="False" RowIndicatorVisibility="Collapsed" IsFilteringAllowed="False" Grid.Row="1"> <telerik:RadGridView.Columns> <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding Change, StringFormat=f4}" /> <telerik:GridViewDataColumn DataMemberBinding="{Binding LastUpdate}" Header="Last Update" /> </telerik:RadGridView.Columns> </telerik:RadGridView> </Grid> </Window>MainWindow.xaml.cs
using System.Windows; namespace RadControlsWpfApp17 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new TestDataContext(); } } } TestDataContext.cs
using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Threading.Tasks; using System.Timers; using Telerik.Windows.Controls; using Telerik.Windows.Data; namespace RadControlsWpfApp17 { class TestDataContext { readonly string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random rnd = new Random(); public DelegateCommand ChangeCommand { get { return new DelegateCommand((o)=> { Task.Factory.StartNew(() => { System.Timers.Timer t=new Timer(); t.Interval = 100; t.Elapsed += new ElapsedEventHandler((sender, e) => { int index = this.rnd.Next(0, this.Source.Count()); StockData item = this.CreateNewStockItem(); this.Source[index].Name = e.SignalTime.ToString(); }); t.Start(); }); }); } } ObservableCollection<StockData> source; ObservableCollection<StockData> Source { get { if (this.source == null) { this.source = new ObservableCollection<StockData>(from i in Enumerable.Range(0, 50) select this.CreateNewStockItem()); } return this.source; } } private StockData CreateNewStockItem() { var item = new StockData(); this.SetRandomPropertyValues(item); return item; } private void SetRandomPropertyValues(StockData item) { item.Name = String.Format("{0}{1}{2}{3}", this.letters[this.rnd.Next(0, this.letters.Count())], this.letters[this.rnd.Next(0, this.letters.Count())], this.letters[this.rnd.Next(0, this.letters.Count())], this.letters[this.rnd.Next(0, this.letters.Count())]); item.LastUpdate = DateTime.Now; item.Change = this.rnd.NextDouble(); } QueryableCollectionView data; public QueryableCollectionView Data { get { if (this.data == null) { this.data = new QueryableCollectionView(Source); this.data.SortDescriptors.Add(new SortDescriptor() { Member = "Name", SortDirection = System.ComponentModel.ListSortDirection.Descending }); } return this.data; } } } public class StockData : INotifyPropertyChanged { private string name; public string Name { get { return this.name; } set { if (this.name != value) { this.name = value; this.OnPropertyChanged("Name"); } } } private double change; public double Change { get { return this.change; } set { if (this.change != value) { this.change = value; this.OnPropertyChanged("Change"); } } } private DateTime lastUpdate; public DateTime LastUpdate { get { return this.lastUpdate; } set { if (this.lastUpdate != value) { this.lastUpdate = value; this.OnPropertyChanged("LastUpdate"); } } } private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; } } 