msword中的无功扩展

时间:2010-12-19 23:11:15

标签: ms-word vsto system.reactive

我想知道是否可以在Word中使用Reactive Extensions。我已经看到了Jeff在这里展示了如何在excel http://social.msdn.microsoft.com/Forums/en/rx/thread/5ace45b1-778b-4ddd-b2ab-d5c8a1659f5f中连接工作簿打开事件。

我想知道我是否能用言语做同样的事情。

我到目前为止......

     public static class ApplicationExtensions
  {
    public static IObservable<Word.Document> DocumentBeforeSaveAsObservable(this Word.Application application)
    {
      return Observable.Create<Word.Document>(observer =>
      {
        Word.ApplicationEvents4_DocumentBeforeSaveEventHandler handler = observer.OnNext;
        application.DocumentBeforeSave += handler;

        return () => application.DocumentBeforeSave -= handler;
      });
    }
  }

但我收到错误'OnNext'没有重载匹配委托'Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentBeforeSaveEventHandler

任何人都可以指出我正确的方向。

此致

麦克

1 个答案:

答案 0 :(得分:1)

您的问题是代理签名的问题。

IObserver<T>.OnNext定义为void (T value)

ApplicationEvents4_DocumentBeforeSaveEventHandler定义为void (Document doc, ref bool SaveAsUI, ref bool Cancel)

如果你只需要发出Document(而不是其他细节,比如让它取消),你可以这样做:

public static IObservable<Word.Document> DocumentBeforeSaveAsObservable(
    this Word.Application application)
{
    return Observable.Create<Word.Document>(observer =>
    {
        Word.ApplicationEvents4_DocumentBeforeSaveEventHandler handler = 
            (doc, ref saveAsUI, ref cancel) => observer.OnNext(doc);

        application.DocumentBeforeSave += handler;

        return () => application.DocumentBeforeSave -= handler;
    });
}

如果确实需要所有数据,则需要创建某种类型的包装类,IObservable序列只能发出一种类型:

public class DocumentBeforeSaveEventArgs : CancelEventArgs
{
    public Document Document { get; private set; }
    public bool SaveAsUI { get; private set; }

    public DocumentBeforeSaveEventArgs(Document document, bool saveAsUI)
    {
        this.Document = document;
        this.SaveAsUI = saveAsUI;
    }
}

然后你可以这样使用它:

public static IObservable<Word.Document> DocumentBeforeSaveAsObservable(
    this Word.Application application)
{
    return Observable.Create<Word.Document>(observer =>
    {
        Word.ApplicationEvents4_DocumentBeforeSaveEventHandler handler = 
            (doc, ref saveAsUI, ref cancel) => 
            {
                var args = new DocumentBeforeSaveEventArgs(doc, saveAsUI);

                observer.OnNext(args);

                cancel = args.Cancel;
            };

        application.DocumentBeforeSave += handler;

        return () => application.DocumentBeforeSave -= handler;
    });
}