我正在尝试在应用程序的“ shell ”中实现WPF扩展工具包中的忙碌指示器。目标是在一个地方实现指标,然后能够在任何地方设置IsBusy属性,以便可以对其进行初始化。这是我的 shell :

<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属性。逻辑工作正常。但是,忙碌指示器无法正常工作。这是另一个切换IsBusy属性的 View 模型的代码片段:
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中的IsBusy状态,该状态不应该在UI线程上。有什么想法或建议吗?

最佳答案

关于我的最后评论。

您可以更改statemanager来执行操作,因此您传入方法,状态管理器可以设置调用等

public static class StateManager
{

public static void Process(Action action) {
    IsBusy = true;
    Application.Current.Dispatcher.Invoke(action, System.Windows.Threading.DispatcherPriority.Background);
    IsBusy = false;
}

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;

}

然后,您可以执行以下操作:
private void SaveCommand_Action()
{
     StateManager.Process(() =>
     {

     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;
});
}

关于c# - 如何在应用程序 shell 中实现繁忙指示器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25194615/

10-13 04:25