[英]RadBusyIndicator not showing PRISM/MEF/WPF from ViewModel
I am using MVVM/PRISM/MEF for my WPF application. 我在WPF应用程序中使用MVVM / PRISM / MEF。 It has one DataGrid with multiple records, and when one row is double clicked a separate view is added to region with multiple controls on it, the initialization of controls takes about 10 seconds for new screen, so thats why I want to show RadBusyIndicator during that time.
它具有一个包含多个记录的DataGrid,并且双击一行时,将单独的视图添加到具有多个控件的区域中,新屏幕的控件初始化大约需要10秒钟,因此这就是为什么我要在此期间显示RadBusyIndicator时间。
Following in the XAML 在XAML中关注
<!-- This is Main View -->
<!-- Module: MainModule, ViewModel: MainViewViewModel -->
<telerik:RadBusyIndicator IsBusy="{Binding IsBusy}" BusyContent="{Binding BusyContent}">
<!-- All PRISM regions are here -->
</telerik:RadBusyIndicator>
Its view model is 它的视图模型是
class MainViewViewModel : ViewModelBase
{
ImportingConstructor]
public MainViewViewModel(IEventAggregator eventAggregator, IRegionManager regionManager, IServiceLocator serviceLocator)
:base(eventAggregator, regionManager, serviceLocator)
{
eventAggregator.GetEvent<BusyStateChangedEvent>().Subscribe(OnBusyStateChanged,ThreadOption.BackgroundThread);
}
#region BusyStateChanged
private void OnBusyStateChanged(bool newState)
{
IsBusy = newState;
}
#endregion
}
And in other view when DataGrid row is double clicked ViewModelBase function is called, as follows 而在其他视图中,当双击DataGrid行时,将调用ViewModelBase函数,如下所示
public class ViewModelBase
{
private NavigationItem global_navItem = null;
public virtual void OnNavigationItemChanged(NavigationItem item)
{
changeNav = true;
global_navItem = item;
//Firing event to change the state
EventAggregator.GetEvent<BusyStateChangedEvent>().Publish(true);
//Using BackgroundWorker, but its not showing any Busy Indicator as well
var bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.RunWorkerAsync();
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Setting busy indicator to false
EventAggregator.GetEvent<BusyStateChangedEvent>().Publish(false);
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
//DisplayView function is taking too long
if (global_navItem != null) this.DisplayView(global_navItem);
}
}
public void DisplayView(NavigationItem item)
{
try
{
//This call is taking long as it initializes the View
MyCustomeUserControl view = this.ServiceLocator.GetInstance<MyCustomeUserControl>(item.viewName);
view.Region = this.Region;
}catch(Exception e)
{
}
}
Events are being fired correctly and view is displayed correctly, but my problem is that Busy indicator is not shown at all, when I double click on DataGrid row the GUI become unresponsive, and after some time the new view appears. 事件被正确触发并且视图正确显示,但是我的问题是“忙”指示器根本没有显示,当我双击DataGrid行时,GUI变得无响应,并在一段时间后出现了新视图。 I am in doubt that this is problem of GUI thread being busy, but what can I do to avoid this, I have used
BackgroudWorker
already? 我怀疑这是GUI线程繁忙的问题,但是我应该怎么做才能避免这种情况,因为我已经使用过
BackgroudWorker
?
EDIT 编辑
1- I am raising PropertyChanged event for IsBusy Property. 1-我正在为IsBusy Property引发PropertyChanged事件。 and I have already tried all options for Thread in event subscription.
并且我已经尝试了事件订阅中Thread的所有选项。 ie
Thread.BackgroundThread
, Thread.UIThread
and Thread.PublisherThread
. 即
Thread.BackgroundThread
, Thread.UIThread
和Thread.PublisherThread
。 but no change. 但没有变化。
2- I have tested Thread.Sleep
rather that DisplayView
in bw_DoWork
, and its showing RadBusyIndicator
properly, so it means that GUI controls are being initialized in GUI thread, no matter I have created a BackgroundWorker
for it. 2-我已经测试了
Thread.Sleep
而不是bw_DoWork
中的DisplayView
,并且正确显示了RadBusyIndicator
,所以这意味着无论我是否为它创建了BackgroundWorker
,都正在GUI线程中初始化GUI控件。
Would the indicator appear if you use Thread.Sleep(5000)
instead of this.DisplayView(global_navItem)
? 如果使用
Thread.Sleep(5000)
而不是this.DisplayView(global_navItem)
Thread.Sleep(5000)
,指示符会出现吗?
I assume showing the view will use the UI thread and this will block the UI no matter you use a BackgroundWorker
or not. 我假设显示视图将使用UI线程,无论您是否使用
BackgroundWorker
,这都会阻塞UI。
Edit: 编辑:
As it seems like your UI loading operation blocks the UI thread and so your BusyIndicator, you can try to host one of them in a different thread. 似乎您的UI加载操作阻塞了UI线程,因此您的BusyIndicator可以尝试将其中一个托管在其他线程中。 An approach is explained in this article .
本文介绍了一种方法。
Finally I have found a solution. 终于我找到了解决方案。 For reference following post can be seen.
作为参考,可以看到以下帖子。 I have implemented a child chrome-less window with RadBusyIndicator using the approach discussed in this post.
我已经使用本文讨论的方法使用RadBusyIndicator实现了一个无铬子窗口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.