【问题标题】:Update progress bar using value present in an internal class使用内部类中存在的值更新进度条
【发布时间】:2012-05-22 06:38:30
【问题描述】:

下面的两个代码段位于不同的命名空间中。第二个代码的访问修饰符是内部的。我正在那里做一些操作,我想计算百分比并在 MgmntApp 进度条中更新。我该怎么做?

WpfApplication1

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Height="204">
        <ProgressBar Height="35" HorizontalAlignment="Left" Margin="57,83,0,0" Name="progressBar1" VerticalAlignment="Top" Width="346" />
    </Grid>
</Window>

我想在下面的类中进行长时间运行的操作时更新进度条的值。

不同

文件解析器.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Different
{
    /// <summary>
    /// </summary>
    internal class FileParser:ImageFileParser
    {
        ImageFileParser.GenerateCmds()
        {
            percentage=change;    //0 to 100
            //long time operation
        }
    }
}

【问题讨论】:

    标签: c# .net wpf xaml progress-bar


    【解决方案1】:

    如果解析需要很长时间,您可能希望在单独的线程上运行它。

    您可以在进度更改时在 FileParser 上引发事件并在 MainWindow 中订阅此事件:

    private void StartParsing()
    {
        FileParser fp = new FileParser("FileName.txt");
        fp.ProgressChanged += FileParser_ProgressChanged;
        Thread t = new Thread(fp.GenerateCmds);
        t.Start();
    }
    
    private void FileParser_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // switch to the UI thread if fileparser is running on a different thread
        Dispatcher.BeginInvoke(new Action(
                                  () => { progressbar.Value = e.ProgressPercentage; }));
    }
    

    为此,您需要将事件添加到 FileParser:

    internal class FileParser:ImageFileParser
    {
        internal event EventHandler<ProgressChangedEventArgs> ProgressChanged;
    
        ImageFileParser.GenerateCmds()
        {
            percentage=change;    //0 to 100
            OnProgressChanged(percentage);
            //long time operation
        }
    
        internal protected void OnProgressChanged(int percentage)
        {
            var p = ProgressChanged;
            if(p != null)
            {
                p(this, new ProgressChangedEventArgs(percentage, null));
            }
        }
    }
    

    【讨论】:

    • 但是 fp.GenerateCmds() 将被另一个名为 PrgmCmdGen 的类调用。如何更新 UI?(我无法访问 UI 的 progressBar1
    • 不要从逻辑中更新视图。为 PrgmCmdGen 类订阅事件并从 PrgmCmdGen 类中公开另一个 ProgressChanged 事件(只需将事件冒泡)并按照我在回答中的建议订阅它。
    • 新 ProgressChangedEventArgs(percentage));这是给出错误。另一个参数 UserState 它的要求。
    • 只需将null 或您想要传递给事件处理程序的对象。
    【解决方案2】:

    为什么不直接绑定到 FileParser 类的属性?

    <ProgressBar Value="{Binding MyFileParser.PercentComplete}" ...
    

    然后让 FileParser 实现 INotifyPropertyChanged

    internal class FileParser:ImageFileParser, INotifyPropertyChanged
    {
        private decimal _pct;
        internal decimal PercentComplete { 
            get { return _pct; }
            set {
                _pct = value;
                PropertyChanged(this, new PropertyChangedEventArgs("PercentComplete"));
            }
        }
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    
        ImageFileParser.GenerateCmds()
        {
            PercentComplete = change;    //0 to 100
            //long time operation
        }
    }
    

    然后根据需要简单地更新 PercentComplete 属性...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-05
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多