【发布时间】:2014-08-08 01:04:39
【问题描述】:
我正在尝试在我的应用程序的“外壳”中实现 WPF 扩展工具包中的繁忙指示器。目标是在一个地方实现指标,然后能够从任何地方设置 IsBusy 属性,以便可以对其进行初始化。这是我的外壳:
<Window x:Class="Foundation.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Library.Controls.Views;assembly=Library"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
WindowStyle="None"
AllowsTransparency="False"
Name="ShellView"
FontFamily="Yu Gothic Light"
Background="{StaticResource AiWhiteBrush}">
<!--Region Outer Most Grid-->
<xctk:BusyIndicator IsBusy="{Binding IsBusy}">
<Grid x:Name="OuterGrid">
<!-- CONTENT HERE -->
</Grid>
</xctk:BusyIndicator>
<!--End Region-->
然后,我的 Shell 的 ViewModel 如下所示:
using CashDrawer.Views;
using Library.BaseClasses;
using Library.StaticClasses;
using Microsoft.Practices.Prism.Commands;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WpfPageTransitions;
namespace Foundation
{
public class ShellViewModel : ViewModelBase
{
#region constructor(s)
public ShellViewModel()
{
StateManager.IsBusyChange += new StateManager.IsBusyHandler(IsBusyEventAction);
}
#endregion constructor(s)
#region properties
private bool _IsBusy;
public bool IsBusy
{
get
{
return _IsBusy;
}
set
{
if (_IsBusy != value)
{
_IsBusy = value;
OnPropertyChanged("IsBusy");
}
}
}
#endregion properties
#region actions, functions, and methods
private void IsBusyEventAction(object sender, EventArgs e)
{
if (StateManager.IsBusy)
{
this.IsBusy = true;
}
else
{
this.IsBusy = false;
}
}
#endregion actions, functions, and methods
}
}
最后,我创建了一个静态 StateManager 类:
using System;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using WpfPageTransitions;
namespace Library.StaticClasses
{
public static class StateManager
{
private static bool _IsBusy;
public static bool IsBusy
{
get
{
return _IsBusy;
}
set
{
if (_IsBusy != value)
{
_IsBusy = value;
IsBusyChange(null, null);
}
}
}
public delegate void IsBusyHandler(object sender, EventArgs e);
public static event IsBusyHandler IsBusyChange;
}
}
这个想法是,当 StateManager 的 IsBusy 属性发生更改时,它将触发一个事件,该事件将相应地更改 ShellViewModel 中的 IsBusy 属性。逻辑工作正常。但是,忙碌指示器未按预期工作。这是另一个视图模型中的代码 sn-p 切换 IsBusy 属性:
private void SaveCommand_Action()
{
StateManager.IsBusy = true;
this.Validate();
if (!HasValidationErrors)
{
if (this.CustomerControlVM.SaveCustomer() != 0)
{
VehicleControlVM.VehicleModel.CustomerID = this.CustomerControlVM.CustomerModel.CustomerID;
this.VehicleControlVM.SaveVehicle();
ComplaintsView complaintsControl = new ComplaintsView();
(complaintsControl.DataContext as ComplaintsViewModel).CurrentVehicle = this.VehicleControlVM.VehicleModel;
(complaintsControl.DataContext as ComplaintsViewModel).CurrentCustomer = this.CustomerControlVM.CustomerModel;
StateManager.LoadView(complaintsControl, PageTransitionType.SlideLeft);
}
}
StateManager.IsBusy = false;
}
我看到代码中有一些滞后,但我从未看到忙碌指示符出现。我可以删除StateManager.IsBusy = false;,然后忙碌指示符会出现(当然会无限期地显示)。我尝试在 IsBusy 状态更改之间创建更长的延迟,但指示符仍然没有出现。我已经阅读了多篇文章和文章,试图了解可能出了什么问题,但我没有看到任何有用的东西。我知道 IsBusy 指示器正在 UI 线程上发生,但我正在更改 ViewModel 中不应出现在 UI 线程上的 IsBusy 状态。有什么想法或建议吗?
【问题讨论】:
-
很可能它是您正在调用的操作的优先级,尝试使用调度程序调用状态更改,其优先级如发送,例如
Dispatcher.Invoke(() => StateManager.IsBusy = true, System.Windows.Threading.DispatcherPriority.Send),这将给它时间在执行逻辑之前渲染指标 -
嗨 sa_ddam213。感谢您的反馈。我试了一下,仍然没有发生。如果我删除 StateManager.IsBusy = false,则逻辑似乎在繁忙指示器出现之前执行。我想你可能正在做某事。还有其他想法吗?
-
也许尝试不同的
DispatcherPriority,甚至可能将逻辑而不是 StateManager.IsBusy 包装在具有背景优先级的 DispatcherInvoke 中,这样指示符将呈现,一旦完成,将调用保存逻辑( make suer IsBusy = false 也在与其他逻辑的调用内部 -
嗯,看起来相反的工作。我没有提高 StateManager.IsBusy = true 的优先级,而是将逻辑包装在一个方法中并使用相同的语法,但优先级为 ,它的工作方式如下:
private void SaveCommand_Action() { StateManager.IsBusy = true; Application.Current.Dispatcher.Invoke(() => Save(), System.Windows.Threading.DispatcherPriority.Background); StateManager.IsBusy = false; } -
哈!我们有同样的想法。我非常感谢您的帮助 sa_ddam213。很好的电话。现在,我只需要干净的方式来实现它,所以我不需要每次调用指标时都这样做。但这是我的问题。非常感谢
标签: c# wpf mvvm wpftoolkit