试着创建一下吧
在 Extension (RC+自定义) 中,提供了用于将菜单项添加、项目文件管理、显示停靠窗口等功能集成到 Epson RC+ 的机制 (扩展点)。
这些功能通过将 Extensions API 提供的扩展点接口,作为 .NET 内置扩展框架 Managed Extensibility Framework (MEF) 的 Export 实现来运行。
在创建 Extension 项目时,可以将所需的扩展点作为 Initial Feature 进行选择,项目创建后也可以作为新项进行添加。
这里将介绍扩展点实现方法的一个示例,并说明从创建 RC+ Extensions 项目到在 Epson RC+ 中使用的流程。
以下步骤中,将在 Extension 的停靠窗口中配置按钮,并创建用于通过 Extension API 接口执行控制器连接/断开的示例。
按照 [开始使用] 的步骤,创建新的 Extension 项目。
- 名称设为 ConnectControllerSample。
- 初始功能勾选 Main menu and tool bar item、和 Docking window。
- 在 ARM64 版 Windows 上,请将配置设置为 x64。
在 Visual Studio 上进行构建和调试,确认功能正常运行。
- 在 Epson RC+ 主菜单的扩展标签下,菜单项中会新增
ConnectControllerSample (xx)(xx 为显示语言名),选择菜单项后若能显示停靠窗口,则表示正常。

- 在 Epson RC+ 主菜单的扩展标签下,菜单项中会新增
模板确认已完成,关闭 Epson RC+。
在 Visual Studio 上编辑 DockingWindow 文件夹下的 DockingWindowContent.xaml 文件。

- 在自动生成配置的 TextBlock 下方的 Grid 内,新增用于控制器连接的 Button 以及用于控制器断开的 Button。
- 请关注 TextBlock 的 Text。它绑定到 Captions[WindowHeader].Value。在 Extension 中,需要根据 Epson RC+ 的显示语言进行本地化的字符串记述在 Captions.xlsx 中。详细内容后述,通过使用 Captions.xlsx 的 symbol 列中定义的名称(本例中为 WindowHeader)以相同方式进行绑定,即可根据 Epson RC+ 的显示语言实现本地化。
<UserControl x:Class="ConnectControllerSample.DockingWindow.DockingWindowContent" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:ConnectControllerSample.DockingWindow" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <UserControl.DataContext> <local:DockingWindowContentViewModel /> </UserControl.DataContext> <DockPanel Background="White" LastChildFill="True"> <TextBlock Margin="3,0,0,0" DockPanel.Dock="Top" FontSize="24" FontWeight="Bold" Foreground="DarkBlue" Text="{Binding Captions[WindowHeader].Value}" /> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button x:Name="ConnectButton" Grid.Row="0" Grid.Column="0" Margin="4" HorizontalAlignment="Left" VerticalAlignment="Top" Command="{Binding ConnectCommand}" Content="Connect Controller" /> <Button x:Name="DisconnectButton" Grid.Row="0" Grid.Column="1" Margin="4" HorizontalAlignment="Left" VerticalAlignment="Top" Command="{Binding DisconnectCommand}" Content="Disconnect Controller" /> </Grid> </DockPanel> </UserControl>编辑 DockingWindow 文件夹下的 DockingWindowContentViewModelAddition.cs 文件。

- 在 .xaml 中新增绑定到控制器连接与断开 Button 的 ConnectCommand 以及 DisconnectCommand 命令。
- 通过参照 IRCXControllerConnectionAPI(控制器连接 API)的 IsOnline 属性,可以确认与机器人控制器的连接状态。IsOnline 在连接建立时为 true,断开时为 false,其他 (如正在尝试连接等中间状态) 为 null。
- 与机器人控制器的连接通过调用 IRCXControllerConnectionAPI 的 ConnectControllerAsync 方法实现。与机器人控制器的断开通过调用控制器连接 API 的 DisconnectControllerAsync 方法实现。
- 消息框的显示通过调用 IRCXWindowAPI(窗口 API)的 ShowMessageBox 方法实现。
- 在构造函数中,通过 Main 类的 GetAPI 方法,从 MEF 容器中获取 IRCXControllerConnectionAPI 以及 IRCXWindowAPI 的实例。
(前略) namespace ConnectControllerSample.DockingWindow { /// <summary> /// Extension : Docking Window (Specific Part) /// </summary> internal partial class DockingWindowContentViewModel { /// <summary> /// Connect controller command /// </summary> public AsyncReactiveCommand ConnectCommand { get; } = new AsyncReactiveCommand(); /// <summary> /// Disconnect controller command /// </summary> public AsyncReactiveCommand DisconnectCommand { get; } = new AsyncReactiveCommand(); /// <summary> /// Window-related API /// </summary> private IRCXWindowAPI _windowAPI; /// <summary> /// Controller Connection API /// </summary> private IRCXControllerConnectionAPI _connectionAPI; /// <summary> /// Constructor /// </summary> public DockingWindowContentViewModel() { _windowAPI = Main.GetAPI<IRCXWindowAPI>(); _connectionAPI = Main.GetAPI<IRCXControllerConnectionAPI>(); ConnectCommand.Subscribe(OnConnect); DisconnectCommand.Subscribe(OnDiscconect); } private async Task OnConnect() { if (_connectionAPI.IsOnline == false) { var result = await _connectionAPI.ConnectControllerAsync(); _windowAPI.ShowMessageBox( new RCXCaption(Main.CommonId, Caption.ExtensionName), new RCXCaption(result ? "Controller connection succeed." : "Controller connection failed."), IRCXWindowAPI.ButtonType.OK, IRCXWindowAPI.IconType.Information); } else { _windowAPI.ShowMessageBox( new RCXCaption(Main.CommonId, Caption.ExtensionName), new RCXCaption("The controller cannot be connected."), IRCXWindowAPI.ButtonType.OK, IRCXWindowAPI.IconType.Warning); } } private async Task OnDiscconect() { if (_connectionAPI.IsOnline == true) { await _connectionAPI.DisconnectControllerAsync(); } else { _windowAPI.ShowMessageBox( new RCXCaption(Main.CommonId, Caption.ExtensionName), new RCXCaption("The controller cannot be disconnected."), IRCXWindowAPI.ButtonType.OK, IRCXWindowAPI.IconType.Warning); } } /// <inheritdoc /> public Task WindowCreated() { return Task.CompletedTask; } } }编辑项目文件夹根目录下的 Captions.xlsx 文件。

- 修改 symbol 列为 WindowHeader 的行中各语言的标题。

重新构建和调试。
- 在启动的 Epson RC+ 中,点击已开发 Extension 的菜单或工具栏图标,显示所创建的 DockingWindow。
- 确认在画面上部显示 Captions.xlsx 中设置的、对应当前 Epson RC+ 语言的标题。
- 确认可通过 [Connect Controller] 按钮和 [Disconnect Controller] 按钮连接和断开控制器。

在 Visual Studio 上编辑 PackageItems 文件夹中的 manifest.rcxmanifest。

- 修改 Vendor Info、Extension Name、Summary、Description 行中各语言的字符串。

按照 [Extension 的分发] 步骤,在扩展功能管理器中显示已开发的 Extension。
- 确认画面上显示 manifest.rcxmanifest 中设置的、对应当前 Epson RC+ 语言的信息。

- 确认画面上显示 manifest.rcxmanifest 中设置的、对应当前 Epson RC+ 语言的信息。
按照 [Extension 的使用] 步骤,启用 Extension,并确认可以使用已开发的功能。