c# - 在这个简单的 WPF 应用程序中实现进度条

标签 c# .net wpf

我有 MainWindow,它有它的 View 模型 MainWindowViewModel。窗口内有一个接受用户输入的文本框、几个用于过滤搜索的单选按钮和一个按钮。使用如下命令将按钮操作绑定(bind)到 View 模型:

<Button x:Name="btnSearch" Command="{Binding SearchByCommand, Mode=OneWay}" />

ViewModel 内部有:

public ICommand SearchByCommand
{
    get
    {
        if (_SearchByCommand == null)
        {
            _SearchByCommand = new RelayCommand(
                x => this.LoadData(this.SearchBy),
                x => { return !string.IsNullOrEmpty(this.SearchText); }
            );
        }
        return _SearchByCommand;
    }
}

和加载数据:

private void LoadData(string searchBy)
{
   switch(searchBy)
   ...
}

这工作得很好,但我不知道如何在此解决方案中实现进度条。当用户单击搜索按钮时,进度条应启动进度并卡住当前 UI。在 LoadData 方法中加载数据后,进度条的进度计数应该结束并再次启用 UI。

最佳答案

您可以使用扩展 WPF 工具包中的忙碌指示器:here .

然后您需要在另一个线程中进行处理 (LoadData),以免卡住 UI。为此,简单的方法是使用后台 worker :

向您的 wm 添加一个 bool 值以指示应用程序何时繁忙:

private bool isBusy;
public bool IsBusy
{
    get { return isBusy; }
    set
    {
        this.isBusy = value;
        this.OnPropertyChanged("IsBusy");
    }
}

设置后台 worker :

private void LoadData(string searchBy)
{
    IsBusy = true;
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (o, ea) =>
    {
        //Do your heavy work here
    };

    worker.RunWorkerCompleted += (o, ea) =>
    {
        IsBusy = false;
    };

    worker.RunWorkerAsync();
}

如果您想显示当前处理进度的进度条,您需要做更多的工作。首先,您需要将自定义样式应用于忙碌指示器:

<toolkit:BusyIndicator IsBusy="True" BusyContent="Processing..." >
    <extToolkit:BusyIndicator.ProgressBarStyle>
        <Style TargetType="ProgressBar">
            <Setter Property="IsIndeterminate" Value="False"/>
            <Setter Property="Height" Value="15"/>
            <Setter Property="Margin" Value="8,0,8,8"/>
            <Setter Property="Value" Value="{Binding ProgressValue}"/>
        </Style>
    </extToolkit:BusyIndicator.ProgressBarStyle>
</toolkit:BusyIndicator>

然后将 ProgressValue 属性添加到您的虚拟机:

private int progressValue ;
public int ProgressValue
{
    get { return progressValue ; }
    set
    {
        this.progressValue = value;
        this.OnPropertyChanged("ProgressValue ");
    }
}

并从后台工作人员报告进度:

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += (o, ea) =>
    {
        //Do your heavy work here
        worker.ReportProgress(10);

        //Do your heavy work here
        worker.ReportProgress(20);

        //And so on
    };

worker.ProgressChanged += (o,ea) =>
    {
        ProgressValue = e.ProgressPercentage;
    };

worker.RunWorkerCompleted += (o, ea) =>
    {
      IsBusy = false;
    };

关于c# - 在这个简单的 WPF 应用程序中实现进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21076203/

相关文章:

c# - 如何在 ASP.NET MVC 4 中将 View 和局部 View 返回到索引布局?

c# - 我应该按照 Visual Studio 的建议将 @Html.Partial 更改为 @Html.PartialAsync 吗?

c# - 注册表值更改错误(对象引用未设置为对象的实例)

c# - 是否有用于 MS Excel 操作(读/写)的 Dot NET (C#) 库?

c# - System.Threading.ThreadPool.QueueUserWorkItem C# 的动态回调方法

c# - 按下 Windows 修饰键时,Keyboard.Modifiers 为 None

c# - Request.Cookies 为 null ASP.NET MVC

.net - 带有 url 编码和符号的查询字符串在 Request.Url 中过早解码

c# - 如何将不同类中的静态属性绑定(bind)到 WPF ListView 的 GridViewColumn?

wpf - 过多的数据绑定(bind)是否会使 WPF 应用程序变慢?有哪些可用的优化技术?