在Windows Ribbon框架中,为了增强用户界面的交互性,经常需要添加各种控件。最近,在项目中添加了对CheckBox和ToggleButton控件的支持。为了展示如何实现这一点,创建了一个名为"10-CheckBox"的新示例,并将其添加到了项目站点上。以下是使用这些控件的Ribbon Markup示例:
<?xml version='1.0' encoding='utf-8' ?>
<Application xmlns='http://schemas.microsoft.com/windows/2009/Ribbon'>
<Application.Commands>
<Command Name="cmdToggleButton" Id="1002" LabelTitle="Toggle Button">
<Command.LargeImages>
<Image>Res/Open32.bmp</Image>
</Command.LargeImages>
<Command.SmallImages>
<Image>Res/Open16.bmp</Image>
</Command.SmallImages>
</Command>
<Command Name="cmdCheckBox" Id="1003" LabelTitle="Check Box">
<Command.LargeImages>
<Image>Res/Save32.bmp</Image>
</Command.LargeImages>
<Command.SmallImages>
<Image>Res/Save16.bmp</Image>
</Command.SmallImages>
</Command>
</Application.Commands>
<Application.Views>
<Ribbon>
<Ribbon.Tabs>
<Tab>
<Group>
<ToggleButton CommandName="cmdToggleButton" />
</Group>
<Group CommandName="cmdGroupCheckBox">
<CheckBox CommandName="cmdCheckBox" />
</Group>
</Tab>
</Ribbon.Tabs>
</Ribbon>
</Application.Views>
</Application>
接下来,将探讨如何在代码后台初始化这些控件,并连接到IUICommandHandler实现。首先,需要创建Ribbon、RibbonToggleButton和RibbonCheckBox的实例,并为按钮的OnExecute事件添加一个事件处理程序:
private Ribbon _ribbon;
private RibbonToggleButton _toggleButton;
private RibbonCheckBox _checkBox;
public Form1()
{
InitializeComponent();
_ribbon = new Ribbon();
_toggleButton = new RibbonToggleButton(_ribbon, (uint)RibbonMarkupCommands.cmdToggleButton);
_checkBox = new RibbonLib.Controls.RibbonCheckBox(_ribbon, (uint)RibbonMarkupCommands.cmdCheckBox);
_button.OnExecute += new OnExecuteEventHandler(_button_OnExecute);
}
然后,需要将IUICommandHandler的实现与辅助类实现连接起来。这涉及到Execute和UpdateProperty方法的实现。以下是Execute方法的一个示例:
public HRESULT Execute(uint commandId, RibbonLib.Interop.UI_ExecutionVerb verb,
ref PropertyKey key, ref PropVariant currentValue, IUISimplePropertySet commandExecutionProperties)
{
switch (commandId)
{
case (uint)RibbonMarkupCommands.cmdToggleButton:
_toggleButton.Execute(verb, ref key, ref currentValue, commandExecutionProperties);
break;
case (uint)RibbonMarkupCommands.cmdCheckBox:
_checkBox.Execute(verb, ref key, ref currentValue, commandExecutionProperties);
break;
}
return HRESULT.S_OK;
}
UpdateProperty方法的实现类似,这里不再赘述。值得注意的是,最新的Ribbon类版本提供了IUICommandHandler的实现,因此用户不再需要自己实现Execute和UpdateProperty方法。
最后,可以通过一个事件处理程序来获取或设置CheckBox的状态。以下是一个示例:
void _button_OnExecute(ref PropertyKey key, ref PropVariant currentValue,
IUISimplePropertySet commandExecutionProperties)
{
MessageBox.Show("checkbox check status is: " + _checkBox.BooleanValue.ToString());
}
以上就是如何在Windows Ribbon中添加CheckBox和ToggleButton控件的详细步骤。通过这种方式,可以为用户提供更加丰富和直观的交互体验。
接下来,将讨论一些关于Ribbon库实现的内部细节。这些内容可能对普通用户来说比较枯燥,但它们对于理解库的内部工作机制非常有帮助。最近,对Ribbon库进行了一次重大的重构。
Ribbon库由以下几个部分组成:
在旧版本的RibbonLib中,控件辅助类有很多重复的代码。例如,每个带有图像属性的控件(LargeImage、SmallImage等)都需要以相同的方式处理这些图像(操作内部变量、通知父Ribbon图像已失效等)。为了解决这个问题,决定重新设计这部分代码。
所做的是将公共代码封装到类中,以便在多个控件中重用,而不需要复制代码。现在,每个Ribbon控件都由几个属性提供者(如ImagePropertiesProvider和TooltipPropertiesProvider)和事件提供者(如ExciteEventsProvider和PreviewEventsProvider)组成。
每个提供者组件都有自己的接口,使用控件也通过将执行委托给组件来实现该接口。例如,有一个ImagePropertiesProvider类实现了IImagePropertiesProvider接口,它暴露了四个图像属性(LargeImage、SmallImage等)。在Button辅助类中,创建了一个ImagePropertiesProvider类型的成员变量,并使Button类也通过调用成员变量上的相应方法来实现IImagePropertiesProvider。
这是一个多重继承真正缺失的情况。作为替代,使用了接口的多重继承、聚合和委托模式。因此,控件仍然有一些重复的代码(委托代码),但这些代码非常简单,没有逻辑。
此外,每个Ribbon控件都需要根据它暴露的属性和事件实现Execute和UpdateProperty方法。因此,制作了一个通用实现,它位于BaseRibbonControl类中,可以在注册的提供者中搜索属性或事件的实现,从而简化了每个控件中的这部分代码(现在它不存在,所知道的最简单的方式)。