- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个我认为相当标准的设置,一个由 ObservableCollection
支持的 ListBox
。
我有一些工作要处理 ObservableCollection
中的 Thing
,这可能需要很长时间(超过几百毫秒),所以我会喜欢将其卸载到 Task
上(我也可以在这里使用 BackgroundWorker
),以免卡住 UI。
奇怪的是,当我在开始 Task
之前执行 CollectionViewSource.GetDefaultView(vm.Things).CurrentItem
时,一切都按预期进行,但是如果发生这种情况 在 Task
期间,CurrentItem
似乎总是指向ObservableCollection
中的第一个元素。
我已经制定了一个完整的工作示例。
XAML:
<Window x:Class="WpfApplication2.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">
<DockPanel>
<ToolBar DockPanel.Dock="Top">
<Button Content="Click Me Sync" Click="ButtonSync_Click" />
<Button Content="Click Me Async Good" Click="ButtonAsyncGood_Click" />
<Button Content="Click Me Async Bad" Click="ButtonAsyncBad_Click" />
</ToolBar>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Path=SelectedThing.Name}" />
<ListBox Name="listBox1" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=Things}" SelectedItem="{Binding Path=SelectedThing}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Window>
C#:
public partial class MainWindow : Window
{
private readonly ViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new ViewModel();
DataContext = vm;
}
private ICollectionView GetCollectionView()
{
return CollectionViewSource.GetDefaultView(vm.Things);
}
private Thing GetSelected()
{
var view = GetCollectionView();
return view == null ? null : (Thing)view.CurrentItem;
}
private void NewTask(Action start, Action finish)
{
Task.Factory
.StartNew(start)
.ContinueWith(t => finish());
//.ContinueWith(t => finish(), TaskScheduler.Current);
//.ContinueWith(t => finish(), TaskScheduler.Default);
//.ContinueWith(t => finish(), TaskScheduler.FromCurrentSynchronizationContext());
}
private void ButtonSync_Click(object sender, RoutedEventArgs e)
{
var thing = GetSelected();
DoWork(thing);
MessageBox.Show("all done");
}
private void ButtonAsyncGood_Click(object sender, RoutedEventArgs e)
{
var thing = GetSelected(); // outside new task
NewTask(() =>
{
DoWork(thing);
}, () =>
{
MessageBox.Show("all done");
});
}
private void ButtonAsyncBad_Click(object sender, RoutedEventArgs e)
{
NewTask(() =>
{
var thing = GetSelected(); // inside new task
DoWork(thing); // thing will ALWAYS be the first element -- why?
}, () =>
{
MessageBox.Show("all done");
});
}
private void DoWork(Thing thing)
{
Thread.Sleep(1000);
var msg = thing == null ? "nothing selected" : thing.Name;
MessageBox.Show(msg);
}
}
public class ViewModel
{
public ObservableCollection<Thing> Things { get; set; }
public Thing SelectedThing { get; set; }
public ViewModel()
{
Things = new ObservableCollection<Thing>();
Things.Add(new Thing() { Name = "one" });
Things.Add(new Thing() { Name = "two" });
Things.Add(new Thing() { Name = "three" });
Things.Add(new Thing() { Name = "four" });
}
}
public class Thing
{
public string Name { get; set; }
}
最佳答案
我相信 CollectionViewSource.GetDefaultView
实际上是线程静态的 - 换句话说,每个线程都会看到不同的 View 。这是一个简短的测试来证明:
using System;
using System.Windows.Data;
using System.Threading.Tasks;
internal class Test
{
static void Main()
{
var source = "test";
var view1 = CollectionViewSource.GetDefaultView(source);
var view2 = CollectionViewSource.GetDefaultView(source);
var view3 = Task.Factory.StartNew
(() => CollectionViewSource.GetDefaultView(source))
.Result;
Console.WriteLine(ReferenceEquals(view1, view2)); // True
Console.WriteLine(ReferenceEquals(view1, view3)); // False
}
}
如果您希望您的任务处理特定项目,我建议您在开始任务之前获取该项目。
关于c# - 为什么 CollectionViewSource.GetDefaultView(...) 从任务线程内部返回错误的 CurrentItem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5489004/
我是一名学生程序员,使用 Qt 开发 GUI 应用程序。我正在使用 QTreeWidget 来显示存储在 vector 中的一些属性。在同一个窗口中,我有编辑、复制和删除按钮。到目前为止,按钮可以完成
这个简单的 WPF-DataGrid 它显示了一个没有问题的绑定(bind)列表,在重新获得焦点时以一种奇怪的方式表现: 首先,用户选择了一行
我有一个 WPF 工具包 DataGrid,它绑定(bind)到 View 模型中的对象的可观察集合。在这个 DataGrid 中,我为该对象的某个字段定义了一个 DataGridTemplateCo
我使用 AvQueuePlayer 在后台播放音频。为了保持 AvQueuePlayer 的播放列表不为空,我使用键值观察来关注 AvQueuePlayer 的 currentItem 以准备加载下一
我正在制作一个使用 AVPlayer 的应用程序。在我的一个观点中,我有一个 UISlider,用户应该能够使用它向前和向后滑动。我在让 seekToTime 按我的意愿工作时遇到了一些问题。当我尝试
您好,我正在使用 AVPlayer 进行视频流传输。这就是我为播放所做的。 avPlayer = AVPlayer(url: videoURL! as URL) playerLayer = AVPla
我正在尝试从 ICollectionView CurrentItem 的属性(相关表 1..Many)在 XAML 中创建一个 CollectionViewSource,但出现此错误: 'System
我有 ViewModel一个集合,带有 ICollectionView view;好吧,在 XAML 中我有 但这很奇怪,因为 CommandParameter单击时未解决。我得到一些不反射(ref
概述 我有一个使用 VSTO 创建的 Outlook 加载项。该加载项有一个用于 Mail.Compose 功能区类型的功能区(可视化设计器)。功能区选项卡 ControlIdType 设置为“自定义
我有一个我认为相当标准的设置,一个由 ObservableCollection 支持的 ListBox。 我有一些工作要处理 ObservableCollection 中的 Thing,这可能需要很长
我正在关注 A simple iOS view to play video这可以帮助您在 UIView 中显示 AVPlayer。这非常有帮助,但不幸的是在 VideoView(自定义创建)中它不包含
我正在使用带有自定义转换的 iCarousel 插件,并尝试制作特定的淡入淡出效果。我想要当前项目褪色之前的所有项目,但当前项目以及之后的所有项目都没有褪色。有没有办法用淡入淡出选项做到这一点?我尝试
如果您在 Activity onCreate() 中有此代码: mViewPager = new ViewPager(this, null); mPagerAdapter = new PagerAda
下面的 XAML 基本上是试图列出 Button s(从当前 Name 中的 Views 集合中的对象的 DataContext 属性呈现。 当我点击一个按钮时,CurrentItem Collect
我想要一个属性到一个ICollectionView的当前项我该怎么做? ICollectionView用于绑定(bind)到组合框,如何将另一个控件绑定(bind)到 ICollectionView的
我正在开发一个项目,其中我在一个屏幕上使用 View Pager,它只有两个页面。 在第一个上,我有一个带有一些小部件的简单表单。在第二页上,我有一些产品名称和数量的 ListView 。 在选择放置
如果我有 DataGrid在我的View和 Property在我的ViewModel表示当前事件的 DataGridRow (例如,焦点项目或单击项目)我应该将我的属性绑定(bind)到 Select
我正在尝试从 QML 中的 ListView 访问角色。本质上,我的 QML 中有这个: ListView { id: myId model: myModel delegate
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我正在使用 mmenu 创建菜单。虽然我愿意听取有关是使用 jquery 还是 PHP 的建议(最佳实践建议),但我需要能够轻松地将我的菜单包含在每个新页面上。我希望这能让更新更容易。 问题是 mme
我是一名优秀的程序员,十分优秀!