In my WPF project. I have:
public partial class MainWindow : Window
{
ObservableCollection<Calls> items = new ObservableCollection<Calls>();
public MainWindow()
{
InitializeComponent();
icTodoList.ItemsSource = items;
this.DataContext = new MainViewModel();
}
icTodoList
is an ItemsControl
, I want to add two columns for it.
<DockPanel>
<ItemsControl Height="300" Name="icTodoList" ItemsSource="{Binding Calls}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding DialingNumber, Mode=OneWay, FallbackValue=' '}" Grid.Column="0"/>
<TextBlock Text="{Binding DialResult, Mode=OneWay, FallbackValue=' '}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl></DockPanel>
As for Calls
class, we have
public class Calls : NotifyUIBase
{
private string dialingNumber;
public string DialingNumber
{
get { return dialingNumber; }
set
{
dialingNumber = value;
RaisePropertyChanged();
}
}
public string dialResult;
public string DialResult {
get { return dialResult; }
set
{
dialResult = value;
RaisePropertyChanged();
}
}
}
NotifyUIBase
inherited from INotifyPropertyChanged
, it contains RaisePropertyChanged
property, ignore writing here for saving space.
Now I have a producer-consumer process by clicking Start
button.
private async void Start_Click(object sender, RoutedEventArgs e)
{
var producer = Producer();
var consumer = Consumer();
await Task.WhenAll(producer, consumer);
}
In consumer
method, we update the ItemsControl.
async Task Consumer()
{
try
{
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 50
};
var consumerBlock = new ActionBlock<AppointmentReminder>(
remainder =>
{
Calls c = new Calls();
c.DialingNumber = "number..";
c.DialResult = "result...;
items.Add(c);
},
executionDataflowBlockOptions);
bufferBlock.LinkTo(
consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });
await Task.Delay(500);
}
However I got an exception:
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
It happened at the line:
items.Add(c);
I guess it is the thread issue, so how to fix it?