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;
}
}