如何从位于另一个程序集中的BackgroundWorker 数据绑定ProgressControl?

2024-04-19

我有一个使用 Galasoft MVVM Toolkit 以 WPF 作为客户端的多程序集项目。我想知道如何将 ProgressControl 的“Value”属性数据绑定到 BackgroundWorker 的 ProgressChanged 事件。

还有其他文章处理这种情况;然而,它们只处理位于虚拟机中的 Worker。我的 Worker 理想地位于 DataService 存储库中,它完成了大部分繁重的工作,如下面的代码所示。

这是我得到的:

在视图中,ProgressControl XAML 是这样的:

<ProgressBar Maximum="{Binding NumberOfPublications}" 
                         Minimum="0" 
                         Height="50" 
                         Margin="10"
                         Value="{Binding Source={StaticResource ConverterEntity},Path=ProgressValue, Mode=OneWay}"
                         Visibility="{Binding Source={StaticResource ConverterEntity}, Path=IsLengthyOperation, Converter={StaticResource Bool2InverseVisibility}}">

绑定源位于另一个程序集中,如下所示:

public class ConverterEntity : ViewModelBase
{
.
.
public int ProgressValue
    {
        get
        {
            return _progressValue;
        }
        set
        {
            _progressValue = value;
            RaisePropertyChanged( ProgressValuePropertyChanged );
        }
    }

回到 App.xaml,我已将必要的引用放入 Windows 资源中,如下所示:

 <Application.Resources>

    <vc:ConverterEntity x:Key="ConverterEntity" />

显然,我可以看到虽然 View xaml 构建得很好,但没有使用“vc”引用...只是想知道它如何正确构建,即使 ProgressBar 不需要“vc”命名法。

无论如何,ViewModel 有一个按钮绑定到运行此代码的命令:

repo.ExtractAllZipArchiveSets(
                        ( s , e ) => 
 ... );

...这是一个执行 grunt 代码的存储库:

 public void ExtractAllZipArchiveSets( Action<ObservableCollection<Publication> 
 , Exception> callback , string rootDirectory ) {
.
.
  DirectoryInfo dirInfo = new DirectoryInfo( rootDirectory );
        BackgroundWorker worker = null;

 Thread.Sleep( 2000 );
                            worker = new BackgroundWorker();
                            worker.DoWork += new DoWorkEventHandler( ExtractZipFile );
                            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler( AddPublicationToBeProcessed );
                            worker.ProgressChanged += ProgressChanged;
                            worker.RunWorkerAsync( zipInfo );
                            worker.WorkerReportsProgress = true;
                            worker.ReportProgress( (dirCounter +=1 ) * 10);
.
.
  }

  public void ProgressChanged( object sender , ProgressChangedEventArgs e )
    {
        //ConverterEntity entity = new ConverterEntity();
        //entity.ProgressValue = e.ProgressPercentage;
    }

 private void AddPublicationToBeProcessed(object sender, RunWorkerCompletedEventArgs e)
    {

    }
    private void ExtractZipFile( object sender , DoWorkEventArgs e )
    {  
            FileInfo fileInfo = new FileInfo( ( e.Argument as FileSystemInfo ).FullName );
            DiskFolder destinationFolder = new DiskFolder( fileInfo.Directory.ToString() );
            DiskFile zipFile = new DiskFile( fileInfo.FullName );
            ZipArchive zip = new ZipArchive( zipFile );
            zip.CopyFilesTo( destinationFolder , true , true , "*.r*" );          
    }

...就是这样。

我不想在虚拟机中使用我的繁琐代码,因为我只想从中调用并执行操作方法。存储库似乎是抽象所有这些工作的适当位置。

也许某种 DependencyObject 可以解决这个问题,而不是像我这样使用实例化和私有字段,这显然是行不通的。

但是,如果我想为 ProgressControl 提供更新,我该怎么做?

谢谢。


You seem缺少一些信息,或者关于如何BackgroundWorker类的工作原理,或者如何从外部项目调用方法......这些都不会阻止您实现目标。

首先,让我们确保您知道如何设置BackgroundWorker。这里不再重复,请参考我给的答案后台工作人员停滞的进度条更新 https://stackoverflow.com/questions/19334583/progress-bar-update-from-background-worker-stalling问题,请参见 StackOverflow。从这个例子来看,这里是ProgressBar.Value属性得到更新:

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
}

就您而言,如果您有数据绑定ProgressValue财产给ProgressBar.ValueUI 中的属性,那么你可以这样做:

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    ProgressValue = e.ProgressPercentage;
}

到目前为止,一切都很好?好的,现在“连接”您的BackgroundWorker 来自另一个程序集。请注意,只要您有对象的实例,那么这并不重要where它被宣布了。从我的例子来看,这是我连接的地方BackgroundWorker:

public TestView()
{
    InitializeComponent();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.ProgressChanged += ProgressChanged;
    backgroundWorker.DoWork += DoWork;
}

唯一的区别是你需要暴露你的BackgroundWorker作为其他程序集的属性...然后您可以像这样使用它:

public TestView()
{
    InitializeComponent();
    classInOtherAssemblyReference.BackgroundWorker.WorkerReportsProgress = true;
    classInOtherAssemblyReference.BackgroundWorker.ProgressChanged += ProgressChanged;
    classInOtherAssemblyReference.BackgroundWorker.DoWork += DoWork;
}

为了澄清这一点,您需要来自其他程序集的类的实例(classInOtherAssemblyReference)在你的 UI 代码后面/视图模型中,并且该类应该有一个BackgroundWorker类型的属性BackgroundWorker.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从位于另一个程序集中的BackgroundWorker 数据绑定ProgressControl? 的相关文章

随机推荐