我有这种情况:
我想在 MainWindow 的 ViewModel 中加载一个集合,我有一个大数据,所以当我进入人员集合的幻灯片时,它应该等待完成加载,然后我可以看到完整列表,我有以下内容:
<ListView .....
ItemsSource{Binding PeopleList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
... />
// ...
private ObservableCollection<Person> _People;
public ObservableCollection<Person> People
{ get{return _People;} set{ _People = value; RaisePropertyChange("People");}}
// ...
我想在加载第一个完全开始加载第二个之后一个一个地加载所有人员列表......等等而不阻塞主窗口我希望我的窗口看起来像:
我厌倦了自己做,但我失败了。之前谢谢。
最佳答案
存在使用 SynchronizationContext 从另一个线程修改 View 的方法。
请看这个例子:
private void Button_Click(object sender, RoutedEventArgs e)
{
var sync = SynchronizationContext.Current;
BackgroundWorker w = new BackgroundWorker();
w.DoWork+=(_, __)=>
{
//sync.Post(p => { button.Content = "Working"; }, null);
int j = 0;
for (int i = 0; i < 10; i++)
{
j++;
sync.Post(p => { button.Content = j.ToString(); }, null);
Thread.Sleep(1000);
}
sync.Post(p => { button.Background = Brushes.Aqua; button.Content = "Some Content"; }, null);
};
w.RunWorkerAsync();
}
这是观点:
<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">
<Grid>
<Button x:Name="button" Content="Some Content" Click="Button_Click"/>
</Grid>
</Window>
此代码多次更新 View (在本例中为按钮)。我认为这解决了您最初的问题。
----编辑----
这是使用这个想法的更好方法:我建议在基本 View 模型中创建这样的方法:
public void LockAndDoInBackground(Action action, string text, Action beforeVisualAction = null, Action afterVisualAction = null)
{
if (IsBusy)
return;
var currentSyncContext = SynchronizationContext.Current;
ActiveThread = new Thread((_) =>
{
currentSyncContext.Send(t =>
{
IsBusy = true;
BusyText = string.IsNullOrEmpty(text) ? "Wait please..." : text;
if (beforeVisualAction != null)
beforeVisualAction();
}, null);
action();
currentSyncContext.Send(t =>
{
IsBusy = false;
BusyText = "";
if (afterVisualAction != null)
afterVisualAction();
}, null);
});
ActiveThread.Start();
}
这样,任何 subview 模型都可以使用它来执行大量数据处理,并且 UI 不会卡住。
IsBusy
和 BusyText
是绑定(bind)到 View 等待消息和等待元素的可见性的 View 模型变量。这是在 subview 模型的命令中使用的示例:
private RelayCommand _SomeCommand;
public RelayCommand SomeCommand
{
get { return _SomeCommand ?? (_SomeCommand = new RelayCommand(ExecuteSomeCommand, CanExecuteSomeCommand)); }
}
private void ExecuteSomeCommand()
{
Action t = ()=>
{
//some action
};
LockAndDoInBackground(t, "Generating Information...");
}
private bool CanExecuteSomeCommand()
{
return SelectedItem != null;
}
希望这将成为一个更清楚的例子。
关于c# - 如何在不阻塞 UI 的情况下在 Binding 中加载控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23109996/