Created
November 3, 2012 16:07
-
-
Save patroza/4007760 to your computer and use it in GitHub Desktop.
ReactiveUI ReactiveCollection AddRange/ItemsAdded repro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Window x:Class="WpfApplication3.MainWindow" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
Title="MainWindow" Height="350" Width="525"> | |
<Grid> | |
<StackPanel Orientation="Horizontal"> | |
<StackPanel Margin="5"> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="Original Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding Col.Count}" /> | |
</StackPanel> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="Manual Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding ManualCount}" /> | |
</StackPanel> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="ListBox Original Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding Items.Count, ElementName=LB}" /> | |
</StackPanel> | |
<TextBlock Text="Original List" /> | |
<ListBox Name="LB" ItemsSource="{Binding Col}"> | |
<ListBox.ItemTemplate> | |
<DataTemplate> | |
<TextBlock Text="{Binding Id}" /> | |
</DataTemplate> | |
</ListBox.ItemTemplate> | |
</ListBox> | |
</StackPanel> | |
<StackPanel Margin="5"> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="Derived Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding DerivedCol.Count}" /> | |
</StackPanel> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="Manual Derived Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding ManualDerivedCount}" /> | |
</StackPanel> | |
<StackPanel Orientation="Horizontal"> | |
<TextBlock Text="ListBox Derived Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding Items.Count, ElementName=DerivedLB}" /> | |
</StackPanel> | |
<TextBlock Text="Derived List" /> | |
<ListBox Name="DerivedLB" ItemsSource="{Binding DerivedCol}"> | |
<ListBox.ItemTemplate> | |
<DataTemplate> | |
<TextBlock Text="{Binding Id}" /> | |
</DataTemplate> | |
</ListBox.ItemTemplate> | |
</ListBox> | |
</StackPanel> | |
<StackPanel Margin="5" Orientation="Horizontal"> | |
<TextBlock Text="Original CollectionChanged Count" /> | |
<TextBlock Margin="5,0,0,0" Text="{Binding CollectionChangedCount}" /> | |
</StackPanel> | |
</StackPanel> | |
</Grid> | |
</Window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Specialized; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Windows; | |
using System.Windows.Threading; | |
using ReactiveUI; | |
namespace WpfApplication3 | |
{ | |
/// <summary> | |
/// Interaction logic for MainWindow.xaml | |
/// </summary> | |
public partial class MainWindow : Window | |
{ | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
DataContext = new MainViewModel(); | |
} | |
} | |
public class Model : ReactiveObject | |
{ | |
static int _UniqueId; | |
public int Id { get; private set; } | |
public Model() | |
{ | |
Id = _UniqueId++; | |
} | |
} | |
public class MainViewModel : ReactiveObject | |
{ | |
ReactiveCollection<Model> _Col; | |
public ReactiveCollection<Model> Col | |
{ | |
get { return _Col; } | |
set { this.RaiseAndSetIfChanged(x => x.Col, value); } | |
} | |
ReactiveCollection<Model> _DerivedCol; | |
public ReactiveCollection<Model> DerivedCol | |
{ | |
get { return _DerivedCol; } | |
set { this.RaiseAndSetIfChanged(x => x.DerivedCol, value); } | |
} | |
int _CollectionChangedCount; | |
public int CollectionChangedCount | |
{ | |
get { return _CollectionChangedCount; } | |
set { this.RaiseAndSetIfChanged(x => x.CollectionChangedCount, value); } | |
} | |
int _ManualCount; | |
public int ManualCount | |
{ | |
get { return _ManualCount; } | |
set { this.RaiseAndSetIfChanged(x => x.ManualCount, value); } | |
} | |
int _ManualDerivedCount; | |
public int ManualDerivedCount | |
{ | |
get { return _ManualDerivedCount; } | |
set { this.RaiseAndSetIfChanged(x => x.ManualDerivedCount, value); } | |
} | |
public MainViewModel() | |
{ | |
// UI Thread | |
Col = new ReactiveCollection<Model>(); | |
Col.CollectionChanged += (sender, args) => { | |
if (args.Action == NotifyCollectionChangedAction.Add) CollectionChangedCount++; | |
}; | |
DerivedCol = new ReactiveCollection<Model>(); | |
Col.ItemsAdded.Subscribe(x => DerivedCol.Add(x)); | |
Col.ItemsRemoved.Subscribe(x => DerivedCol.Remove(x)); | |
// Add single item - Works | |
Col.Add(new Model()); | |
UpdateManualCounts(); | |
// Add range - Fails | |
Col.AddRange(new[] { new Model(), new Model() }); | |
UpdateManualCounts(); | |
// Worker Thread | |
Task.Factory.StartNew(() => | |
{ | |
while (true) | |
{ | |
// Add single item - Works | |
DispatcherInvoke(() => Col.Add(new Model())); | |
// Add Range - Fails in beginning, but magically starts working again | |
DispatcherInvoke(() => Col.AddRange(new[] { new Model(), new Model() })); | |
UpdateManualCounts(); | |
Thread.Sleep(2000); | |
} | |
}); | |
} | |
private void DispatcherInvoke(Action action) | |
{ | |
Application.Current.Dispatcher.Invoke(action); | |
} | |
private void UpdateManualCounts() | |
{ | |
ManualCount = Col.Count(); | |
ManualDerivedCount = DerivedCol.Count(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment