如何将对Excel StatusBar的引用传递给C#中的另一个类?

ilmyapht  于 11个月前  发布在  C#
关注(0)|答案(2)|浏览(112)

我有一个简单的XLL(Excel加载项),它使用C#来:
1.从模板工作簿(XLSX)收集一些简单的输入。
1.决定(基于该输入)用户试图从哪个第三方软件中提取数据;然后调用适当的DLL连接到相关的软件包。
1.接收一个标准化的数据结构(我在Interfaces.dll中定义的自定义对象的集合),并将其写入Excel工作表。
在结构上,我有一个 *.csproj用于顶级入口点(XLL),另一个用于Interfaces.dll(这样所有其他项目都可以看到我为传递数据而定义的IO类的定义)。然后,我为每个第三方软件都有一组兄弟项目来执行所需的COM交互。这意味着我的顶级-XLL级别的项目是唯一一个“知道"Excel的项目,并获得对Excel应用程序对象的引用(通过ExcelDNA和Microsoft.Office.Interop.Excel)-但我的较低级别的项目只需要”看到“第三方软件的相应COM对象。
问题是,一些数据收集需要一段时间,用户希望看到Excel状态栏更新的不同类别的数据收集正在进行-我不需要一个进度条,只是一些高级别的说明,如“提取流数据”,“提取泵数据”等。是否有一个优雅的方式来传递引用我的XLL具体地说,是否可以只传递对Excel Application.StatusBar文本字段的引用?
我的代码看起来像这样:

xl.Application app = (xl.Application)ExcelDnaUtil.Application;  // This gets the root Excel Application object from the Excel-DNA environment
app.StatusBar = "Starting export"

HysysExport.HysysExporter exporter = new HysysExport.HysysExporter(sim_version, CompMap, HexMap);
results = exporter.GetData();

字符串
其中HysysExport是我的一个较低级别的DLL,它有一个类构造函数,传入一些Map字典和软件版本号。
我想知道是否可以传入一个指向app.StatusBar的引用/指针,类似于:

HysysExport.HysysExporter exporter = new HysysExport.HysysExporter(sim_version, CompMap, HexMap, ref app.StatusBar);
results = exporter.GetData();


其中HysysExport.HysysExporter的类构造函数如下所示:

public HysysExporter(string simVersion, Dictionary<string, string> CompMap, Dictionary<string, string[]> HexMap, ref string xlStatus)
{
    this.simVersion = simVersion;
    this.CompMap = CompMap;
    this.HexMap = HexMap;
    this.xlStatus = xlStatus;
}


类似的东西会起作用吗?我需要什么形式来定义class字段来存储对字符串的引用,而不是副本?这甚至可以使用Excel app.StatusBar字段,因为Visual Studio在我尝试通过引用传递它时会给我一个错误。
我使用的是.Net 4.8 -所以我可以看到的一些选项在以后的版本中可用,现在可能超出了我的范围。

hgb9j2n6

hgb9j2n61#

由于StatusBar文本将在构造函数中更新一次,因此您需要像第一个代码片段那样在外部进行更新。从OOP的Angular 来看,这将是更好的方法。
一般来说,它可以通过回调方法或像NotifyPropertyChanged这样的接口来解决,但是你想要与之交互的类应该支持任何这些。
不能传递“ref app.StatusBar”,因为StatusBar是一个属性而不是字段。事实上,属性是两个方法getset的集合。只有在访问包括StatusBar在内的app变量之后,才能传递app变量。
在您的特定情况下,由于您的应用程序是Excel加载项,因此有必要使应用程序变量全局(静态)可从任何位置访问,并且不要将其作为参数传递。

static class HysysExport {
  static xl.Application app;
  class HysysExporter {
    public HysysExporter(string simVersion, Dictionary<string, string> CompMap, Dictionary<string, string[]> HexMap, string xlStatus) {
      simVersion = simVersion;
      CompMap = CompMap;
      HexMap = HexMap;
      app.StatusBar = xlStatus;
    }
  }
  static void YourInitMethod() {
    app = (xl.Application)ExcelDnaUtil.Application;
    app.StatusBar = "Starting export";
  }
}

字符串
但是这种方法看起来并不好--你需要在每个构造函数中包含状态栏更新。
为了进一步开发方法,Factory method pattern可以帮助您简化代码并使其更加可靠。
在Factory方法中,您将在创建每个新对象后更新StatusBar。

qyzbxkaa

qyzbxkaa2#

受到@rotabor的回答的启发,我最终做了以下事情:将xlApp对象移动为现有“interfaces”DLL的静态成员(我用它来定义所有其他项目的接口,即它们已经具有该类的相关范围可见性),然后我可以从任何地方访问该静态对象-这在这里起作用,因为Excel应用程序对象是静态的,根据定义,对于一个XLL -这一事实是关键,所以感谢@rotabor提示我在这个方向!
所以我的接口项目有:

public class SimIO
{
    public static xl.Application xlApp = (xl.Application)ExcelDnaUtil.Application;
    [... other code defining the interface class]
}

字符串
然后在其他地方我可以使用,例如:

SimIO.xlApp.StatusBar = "Writing data to Excel";

相关问题