为啥我的 Silverlight BusyIndi​​cator 在设置 IsBusy = true 后仍然不可见?

Posted

技术标签:

【中文标题】为啥我的 Silverlight BusyIndi​​cator 在设置 IsBusy = true 后仍然不可见?【英文标题】:Why does my Silverlight BusyIndicator stay invisible after setting IsBusy = true?为什么我的 Silverlight BusyIndi​​cator 在设置 IsBusy = true 后仍然不可见? 【发布时间】:2011-06-15 06:09:08 【问题描述】:

当 DomainDataSource 获取数据时,我的 BusyIndi​​cator 会按预期工作。但是当我在代码中将 IsBusy 设置为 true 时,控件仍然不可见。

我正在使用 Silverlight 4 和 BusyIndi​​cator 工具包。在 XAML 中,我已将 BusyIndi​​cator.IsBusy 属性绑定到我的 DomainDataSource 控件的 IsBusy 属性。 BusyIndi​​cator 控件包装了我的主 Grid (LayoutRoot) 和所有子控件。

<toolkit:BusyIndicator IsBusy="Binding ElementName=labSampleDomainDataSource, Path=IsBusy"  Name="busyIndicator1">
<Grid x:Name="LayoutRoot">

</Grid>
</toolkit:BusyIndicator>

问题是当我设置busyIndi​​cator1 = true时BusyIndi​​cator不显示;在按钮单击事件中。知道我做错了什么吗?

【问题讨论】:

移除绑定后会发生什么? 当我删除绑定时,BusyIndi​​cator 仍然不显示。但是在我的按钮单击事件结束之前,UI 似乎确实被锁定/禁用了。另外,我注意到如果我注释掉 IsBusy = false; (离开 IsBusy = true;)然后在单击事件代码完成后会出现 BusyIndi​​cator。当然,BI 也永远不会消失,我的程序也毫无用处。我不明白它为什么会这样。 似乎是布局问题。 BusyIndi​​cator 是否位于 Silverlight 应用程序的根目录?或者您可以发布您的整个 XAML 吗? BusyIndi​​cator 是 【参考方案1】:

UI 会在 UI 线程上自然更新。按钮点击等事件也会在 UI 线程上运行。

在某些情况下,属性更改和对控件的方法调用会导致方法被分派到 UI 线程。这意味着要调用的方法实际上不会发生,直到 UI 线程可以执行它(并且已经执行了任何其他已经排队的东西)。 IsBusy 属于这一类。

只有当您的代码完成 UI 线程后,UI 才有机会更新其外观。您不应该在 UI 线程中执行任何长时间运行的任务。在您的情况下,您将线程捆绑起来进行自己的竞标,并使 UI 缺乏可用于完成工作的线程。

相反,您应该考虑使用 BackgroundWorker 类并在其运行在不同线程上的 DoWork 事件中完成所有繁重的工作。

myButton_Click(object sender, RoutedEventArgs e)

    isbusyindicator1.IsBusy = true;
    var bw = new BackgroundWorker();
    bw.DoWork += (s, args) =>
    
       //Stuff that takes some time
    ;
    bw.RunWorkerCompleted += (s, args) =>
    
         isbusyindicator1.IsBusy = false;
    ;
    bw.RunWorkerAsync();

现在这个点击事件很快完成,允许使用 UI 线程更新 UI,而实际工作在后台线程上完成。完成后 IsBusy 将被清除。

【讨论】:

谢谢!很好的解释-我已将其标记为答案。但它提出了新的问题,即 BackgroundWorker 允许执行哪些耗时的任务。我正在尝试调用 ((IEditableCollectionView)DomainDataSource.DataView).AddNew 并使用默认值填充返回的 EF 实体。出于某种原因,当我将该代码放入 BackgroundWorker.DoWork 进程时,什么也没有发生。也许我需要学习更好的方法来预填充 DomainDataSource 的新记录。同时,我发现我可以用 this.Cursor = Cursors.Wait 开始我的 button_click 并用 this.Cursor = Cursors.Arrow 结束它。 @DeveloperDan:其中的变量太多,无法给出合理的答案。有两个基本原则要保持平衡,将繁重的计算和阻塞操作保持在 UI 线程之外,并在 UI 线程上改变 UI 本身。一旦你进入了所有这些 DomainData、View 和 EF 的东西,如果你没有按照预期的模式使用它们,事情就会变得棘手。

以上是关于为啥我的 Silverlight BusyIndi​​cator 在设置 IsBusy = true 后仍然不可见?的主要内容,如果未能解决你的问题,请参考以下文章

消息框的 Silverlight BusyIndi​​cator 背景颜色

Silverlight 4 - BusyIndi​​cator 使用 DomainDataSource

找不到包含 BusyIndi​​cator 的程序集

为啥访问我的 Storyboard x:Name 在 Silverlight 中有效,但在 WPF 中无效?

我无法从Silverlight业务应用程序中的代码中获取查询结果

如何强制 BusyIndi​​cator?