我有一个DataGrid,它通过异步方法从ViewModel填充数据.我的DataGrid是:
<DataGrid ItemsSource="{Binding MatchObsCollection}" x:Name="dataGridParent"
Style="{StaticResource EfesDataGridStyle}"
HorizontalGridLinesBrush="#DADADA" VerticalGridLinesBrush="#DADADA" Cursor="Hand" AutoGenerateColumns="False"
RowDetailsVisibilityMode="Visible" >
Run Code Online (Sandbox Code Playgroud)
我正在使用http://www.amazedsaint.com/2010/10/asynchronous-delegate-command-for-your.html在我的viewmodel中实现异步方式.
这是我的viewmodel代码:
public class MainWindowViewModel:WorkspaceViewModel,INotifyCollectionChanged
{
MatchBLL matchBLL = new MatchBLL();
EfesBetServiceReference.EfesBetClient proxy = new EfesBetClient();
public ICommand DoSomethingCommand { get; set; }
public MainWindowViewModel()
{
DoSomethingCommand = new AsyncDelegateCommand(
() => Load(), null, null,
(ex) => Debug.WriteLine(ex.Message));
_matchObsCollection = new ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC>();
}
List<EfesBet.DataContract.GetMatchDetailsDC> matchList;
ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC> _matchObsCollection;
public ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC> MatchObsCollection
{
get { return _matchObsCollection; }
set
{
_matchObsCollection = value;
OnPropertyChanged("MatchObsCollection");
}
}
// …Run Code Online (Sandbox Code Playgroud) 我有一个这样的列表:
List<Controls> list = new List<Controls>
Run Code Online (Sandbox Code Playgroud)
如何处理在此列表中添加新位置?
当我做:
myObject.myList.Add(new Control());
Run Code Online (Sandbox Code Playgroud)
我想在我的对象中做这样的事情:
myList.AddingEvent += HandleAddingEvent
Run Code Online (Sandbox Code Playgroud)
然后在我的HandleAddingEvent委托处理中添加位置到此列表.我该如何处理添加新的位置事件?我怎样才能举办这个活动?
ObservableCollection我班上有一个.进一步进入我的课程,我有一个主题.从这个线程我想添加到我的ObservableCollection.但我不能这样做:
这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection.
请注意,这不是从UI线程发生的,因此我无权访问调度程序.
我正在使用ListView控件来显示一些数据行.有一个后台任务接收列表内容的外部更新.新接收的数据可能包含更少,更多或相同数量的项目,并且项目本身也可能已更改.
在ListView.ItemsSource绑定到OberservableCollection(_itemList),以便更改_itemList应在也可以看到ListView.
_itemList = new ObservableCollection<PmemCombItem>();
_itemList.CollectionChanged += new NotifyCollectionChangedEventHandler(OnCollectionChanged);
L_PmemCombList.ItemsSource = _itemList;
Run Code Online (Sandbox Code Playgroud)
为了避免刷新完整的ListView,我将新检索的列表与当前_itemList进行简单比较,更改不相同的项目,并在必要时添加/删除项目.集合"newList"包含新创建的对象,因此替换_itemList中的项目正确地发送"刷新"通知(我可以使用OnCollectionChangedObservableCollection 的事件处理程序进行记录)
Action action = () =>
{
for (int i = 0; i < newList.Count; i++)
{
// item exists in old list -> replace if changed
if (i < _itemList.Count)
{
if (!_itemList[i].SameDataAs(newList[i]))
_itemList[i] = newList[i];
}
// new list contains more items -> add items
else
_itemList.Add(newList[i]);
}
// new list contains less items …Run Code Online (Sandbox Code Playgroud) 在多线程WPF应用程序中,无法ObservableCollection从WPF窗口线程以外的线程更新.
我知道有解决方法,所以我的问题不是如何避免" 这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection "异常.
我的问题是,为什么会有这样的例外?为什么不允许从任何线程进行集合更新?
就个人而言,当ObservableCollection从其他线程更改时,我认为没有任何理由阻止UI更新.如果两个线程(包括并行线程)访问同一个对象,一个通过事件监听对象属性的更改,另一个执行更改,它将始终有效,至少在正确使用锁定的情况下.那么,原因是什么?
从Backgroundworker更新ViewModel的UI绑定属性是否存在任何潜在问题?我正在尝试在绑定到UI时更新VM,并且可能用户可能正在键入...同步如何工作(我不认为我可以使用来自XAML的Lock语句).
提前致谢..
这听起来像是一个微不足道的问题,但我在网上找不到任何有效的东西。我正在使用PRISM并且在我走开之前迈出了一步,永远不会回到这个框架。原因如下:
我有漂亮ObservableCollection,如果我给你一个列表,并忘掉它基本的工作原理。但这不是 的目标ObservableCollection,对吧?它改变了..所以,这是集合:
<DataGrid ItemsSource="{Binding Items, Mode=TwoWay}" AutoGenerateColumns="True" />
private ObservableCollection<Item> _items = new ObservableCollection<Item>();
public ObservableCollection<Item> Items
{
get { return _items; }
set { SetProperty(ref _items, value); }
}
Run Code Online (Sandbox Code Playgroud)
所以,这里是:
Items = InitializeItems(); // Works great!
Items.Add(new Item() { ItemId = 1 }); // Also works
Run Code Online (Sandbox Code Playgroud)
但是之后..
for (int i = 1; i < 10; i++)
{
Items.Add(new Item() { ItemId = i });
}
Run Code Online (Sandbox Code Playgroud)
失败.. 有时,除了:
PresentationFramework.dll 中出现类型为“System.InvalidOperationException”的未处理异常 附加信息:ItemsControl 与其项目源不一致。
AddRange() …
我现在正在撞击虚拟墙几天.BindingOperations.EnableSynchronization方法似乎只在.NET 4.5中起作用.
我写了一个有时失败的测试:
object blah = new object();
Application app = Application.Current == null ? new Application() : Application.Current;
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
ObservableCollection<ThreadSafeObservableTestObject> collection = null;
collection = new ObservableCollection<ThreadSafeObservableTestObject>();
BindingOperations.EnableCollectionSynchronization(collection, blah);
CollectionTestWindow w = new CollectionTestWindow();
Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
w.TestCollection = collection;
collection.CollectionChanged += collection_CollectionChanged;
collection.Add(new ThreadSafeObservableTestObject() { ID = 1, Name = "Sandra Bullock" });
collection.Add(new ThreadSafeObservableTestObject() { ID = 2, Name = "Jennifer Aniston" });
collection.Add(new ThreadSafeObservableTestObject() { ID = 3, Name = "Jennifer Lopez" });
collection.Add(new …Run Code Online (Sandbox Code Playgroud) 我正在研究一个WPF应用程序,发现属性更改了绑定属性的通知可能发生在后台线程中,但是对于observablecollection(如添加或删除项目)的任何更改都必须从UI线程发生.我的问题是为什么会这样?INotifyPropertyChanged和INotifyCollectionChanged都是由UI控件订阅的,那么为什么INotifyPropertyChanged会出现异常呢?
例如:
public class ViewModel : INotifyPropertyChanged
{
ObservableCollection<Item> _items = new ObservableCollection<Item>();
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
//Can fire this from a background thread without any crash and my
//Name gets updated in the UI
InvokePropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
public void Add(Item item)
{
//Cant do this from a background thread and has to marshal.
_items.Add(item);
}
public event PropertyChangedEventHandler PropertyChanged;
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler …Run Code Online (Sandbox Code Playgroud) 我的问题非常简单我有一个包含类型的(私有)对象的类ObservableCollection<T>,现在我想运行一些线程(按顺序,因此ThreadPool而不是BackgroundWorkers),它们将新项添加到ObservableCollection<T>.
如果是,ObservableCollection<T>那么说,a ProgressBar,一切都会很简单( - > Invoke),但我不知道如何调用该ObservableCollection<T>对象.
我的目标是拥有一个BackgroundWorker可以运行顺序的东西.
先感谢您.