我有这样的组件,无法改变它:
public sealed class UFScannerManager
{
public UFScannerManager(ISynchronizeInvoke synInvoke);
public ScannerList Scanners { get; }
public event UFS_SCANNER_PROC ScannerEvent;
public UFS_STATUS Init();
public UFS_STATUS Uninit();
public UFS_STATUS Update();
[DefaultMember("Item")]
public sealed class ScannerList
{
public ScannerList(UFScannerManager Owner);
public UFScanner this[int Index] { get; }
public UFScanner this[string ScannerID] { get; }
public UFScanner this[IntPtr ScannerHandle] { get; }
public int Count { get; }
}
}
我想创建一个像这样的组件实例:UFScannerManager(this)
,但在WPF中我不能将pass this
作为参数调用。这里this
表示当前窗口表单对象,构造函数需要ISynchronizeInvoke sysInvoke
参数。因此,在传递this
时,可以在Windows窗体应用程序中正确初始化扫描程序。无需担心ISynchronizeInvoke
界面。
UFS_STATUS ufs_res;
UFScannerManager ScannerManager;
int nScannerNumber;
ScannerManager = new UFScannerManager(this);
ufs_res = ScannerManager.Init();
nScannerNumber = ScannerManager.Scanners.Count;
但是,此代码在WPF中不起作用。问题是这一行。它不喜欢的是this
。
ScannerManager = new UFScannerManager(this);
当我尝试构建时,出现错误:
参数1:无法从'win_myapp'转换为'System.ComponentModel.ISynchronizeInvoke'
答案 0 :(得分:1)
WPF不像ISynchronizeInvoke
类那样提供System.Windows.Forms.Form
实现。所以你需要创建一个。
幸运的是,WPF的Dispatcher
类为该实现提供了所有必需的方法。您只需为Dispatcher
和DispatcherOperation
创建包装器/适配器。
我可以告诉你如何做到这一点。请注意,此代码不应“按原样”在生产环境中使用,因为它已经简化并且没有异常处理。
class DispatcherSynchronizeInvoke : ISynchronizeInvoke
{
private readonly Dispatcher dispatcher;
public DispatcherSynchronizeInvoke(Dispatcher dispatcher)
{
this.dispatcher = dispatcher;
}
public IAsyncResult BeginInvoke(Delegate method, object[] args)
{
// Obtaining a DispatcherOperation instance
// and wrapping it with our proxy class
return new DispatcherAsyncResult(
this.dispatcher.BeginInvoke(method, DispatcherPriority.Normal, args));
}
public object EndInvoke(IAsyncResult result)
{
DispatcherAsyncResult dispatcherResult = result as DispatcherAsyncResult;
dispatcherResult.Operation.Wait();
return dispatcherResult.Operation.Result;
}
public object Invoke(Delegate method, object[] args)
{
return dispatcher.Invoke(method, DispatcherPriority.Normal, args);
}
public bool InvokeRequired => !this.dispatcher.CheckAccess();
// We also could use the DispatcherOperation.Task directly
private class DispatcherAsyncResult : IAsyncResult
{
private readonly IAsyncResult result;
public DispatcherAsyncResult(DispatcherOperation operation)
{
this.Operation = operation;
this.result = operation.Task;
}
public DispatcherOperation Operation { get; }
public bool IsCompleted => this.result.IsCompleted;
public WaitHandle AsyncWaitHandle => this.result.AsyncWaitHandle;
public object AsyncState => this.result.AsyncState;
public bool CompletedSynchronously => this.result.CompletedSynchronously;
}
}
使用此自定义ISynchronizeInvoke
实现,您可以实例化您的类:
// Assuming you're calling this inside of a DispatcherObject, e.g. a Window
new UFScannerManager(new DispatcherSynchronizeInvoke(this.Dispatcher));