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

C# 如何从位于另一个程序集中的BackgroundWorker数据绑定ProgressControl?,c#,wpf,xaml,data-binding,mvvm,C#,Wpf,Xaml,Data Binding,Mvvm,我有一个多组件项目,使用Galasoft MVVM工具包以WPF作为客户端。我想知道如何将ProgressControl的“Value”属性数据绑定到BackgroundWorker的ProgressChanged事件 还有其他一些文章论述了这种情况;但是,它们只处理位于VM中的工人。我的工作人员理想地位于DataService存储库中,该存储库完成了大量的繁重工作,如下面的代码所示 以下是我得到的: 在视图中,ProgressControl XAML如下所示: <ProgressBar

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

还有其他一些文章论述了这种情况;但是,它们只处理位于VM中的工人。我的工作人员理想地位于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}}">
回到App.xaml中,我在Windows资源中添加了必要的引用,如图所示:

 <Application.Resources>

    <vc:ConverterEntity x:Key="ConverterEntity" />
。。。这是一个执行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*" );          
    }
public void extractallziparchiveset(操作回调,字符串根目录){
.
.
DirectoryInfo dirInfo=新的DirectoryInfo(rootDirectory);
BackgroundWorker-worker=null;
《睡眠》(2000年);
worker=新的BackgroundWorker();
worker.DoWork+=新的doworkenventhandler(提取ZipFile);
worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(添加publicationtobeprocessed);
worker.ProgressChanged+=ProgressChanged;
worker.RunWorkerAsync(zipInfo);
worker.WorkerReportsProgress=true;
工人报告进度((dirCounter+=1)*10);
.
.
}
public void ProgressChanged(对象发送方,progresschangedventargs e)
{
//ConverterEntity=新ConverterEntity();
//entity.ProgressValue=e.ProgressPercentage;
}
私有void AddPublicationToBeProcessed(对象发送方、RunWorkerCompletedEventArgs e)
{
}
私有void ExtractZipFile(对象发送方,DoWorkEventArgs e)
{  
FileInfo FileInfo=newfileinfo((例如,参数为FileSystemInfo.FullName);
DiskFolder destinationFolder=新的DiskFolder(fileInfo.Directory.ToString());
DiskFile zipFile=新的DiskFile(fileInfo.FullName);
ZipParchive zip=新ZipParchive(zipFile);
CopyFilesTo(destinationFolder,true,true,*.r*);
}
。。。就这样

我不希望我的grunt代码出现在VM中,因为我只想从VM中调用并执行操作方法。存储库似乎是提取所有这些工作的合适场所

也许某种DependencyObject会起作用,而不是像我使用的那样使用实例和私有字段,这显然不起作用

但是,如果我想为ProgressControl提供更新,我将如何做

多谢各位

您似乎缺少了一些信息,要么是关于
BackgroundWorker
类如何工作,要么是关于如何从外部项目调用方法。。。这两件事都不会阻止你实现目标

首先,让我们确保您知道如何设置
BackgroundWorker
。不要在这里重复我的话,请参考我在StackOverflow上对这个问题的回答。从该示例中,以下是更新
ProgressBar.Value
属性的位置:

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
}
在您的情况下,如果将
ProgressValue
属性的数据绑定到UI中的
ProgressBar.Value
属性,那么您应该执行以下操作:

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    ProgressValue = e.ProgressPercentage;
}
到目前为止还好吗?好的,现在从另一个程序集“连接”您的
BackgroundWorker
。请注意,只要您有一个对象的实例,那么在哪里声明它实际上并不重要。在我的示例中,这里是我连接
BackgroundWorker
的地方:

public TestView()
{
    InitializeComponent();
    backgroundWorker.WorkerReportsProgress = true;
    backgroundWorker.ProgressChanged += ProgressChanged;
    backgroundWorker.DoWork += DoWork;
}
唯一的区别是您需要将
BackgroundWorker
作为另一个程序集的属性公开。。。然后,您可以这样使用它:

public class ConverterEntity : ViewModelBase
{
.
.
public int ProgressValue
    {
        get
        {
            return _progressValue;
        }
        set
        {
            _progressValue = value;
            RaisePropertyChanged( ProgressValuePropertyChanged );
        }
    }
public TestView()
{
    InitializeComponent();
    classInOtherAssemblyReference.BackgroundWorker.WorkerReportsProgress = true;
    classInOtherAssemblyReference.BackgroundWorker.ProgressChanged += ProgressChanged;
    classInOtherAssemblyReference.BackgroundWorker.DoWork += DoWork;
}
为了澄清这一点,您需要一个来自UI代码隐藏/视图模型中另一个程序集(
ClassInTheraseMblyReference
)的类的实例,并且该类应该具有
BackgroundWorker
类型的
BackgroundWorker
属性

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