我正在寻找一种方法来提供一种可插入的方式来向.NET 4.5功能区添加项目,并且已经取得了一些进展,但不是我喜欢的方式:
[InheritedExport]
public interface IRibbonItem
{
void Compose(DesignerRibbon ribbon);
}
public class TestItem : IRibbonItem
{
public void Compose(CustomRibbon ribbon)
{
ribbon.ApplicationMenu.Items.Add((new RibbonApplicationMenuItem() { Header = "_Hello, World!" }));
}
}
public class MEFRibbon : System.Windows.Controls.Ribbon.Ribbon
{
[ImportMany]
private IEnumerable<IRibbonItem> _oRibbons = null;
public MEFRibbon() : base()
{
this.ApplicationMenu = new RibbonApplicationMenu();
MEFHelper.Instance.ComposeParts(this);
this._oRibbons.ToList().ForEach(x => x.Compose(this));
}
}
虽然这有效但看起来很混乱。我更喜欢写所有的插件&#39; XAML中的内容。有没有办法实现这个目标?
我所看到的所有内容都引用旧功能区或其他库。
感谢。
答案 0 :(得分:2)
到目前为止,我遇到了同样的问题。 我计划实现的目标:
RibbonTabViewModel
,RibbonButtonViewModel
等),因为这会导致类的并行层次结构,并限制XAML的功能。 这是我用过的方法
我的所有插件都装有[ApplicationExtension(...)]
并实施IApplicationExtension
:
public interface IApplicationExtension
{
void Startup();
bool CanShutdown();
void Shutdown();
}
ApplicationExtension
声明为:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class ApplicationExtensionAttribute : ExportAttribute, IApplicationExtensionMetadata
{
public ApplicationExtensionAttribute(/* ... */)
: base(typeof(IApplicationExtension))
{
this.Name = name;
this.UICompositionOrder = uiCompositionOrder;
}
// ...
}
IApplicationExtensionMetadata
- 一些元数据,例如显示名称等。
主机应用程序反过来实现此接口:
public interface IApplicationInfrastructureProvider : IInfrastructureProvider
{
ICollection<ViewModel> RibbonTabs { get; }
ICollection<ViewModel> ApplicationMenuItems { get; }
ICollection<ViewModel> QuickAccessToolbarItems { get; }
ICollection<ViewModel> StatusBarItems { get; }
}
其中ViewModel
- 一些基本视图模型类,并通过MEF加载插件:
[ImportMany]
private IEnumerable<Lazy<IApplicationExtension, IApplicationExtensionMetadata>> Extensions { get; set; }
当应用程序初始化时,它会为每个插件调用Startup
方法
这里的插件实现能够通过IApplicationInfrastructureProvider
作为视图模型添加选项卡,菜单项等,以扩展应用程序的UI。
请注意,这些视图模型不是任何RibbontTabViewModel
或RibbonButtonViewModel
。它们只是一些功能。
如何在UI方面工作。
例如,当RibbonTabs
集合发生更改时,应用程序会调用执行此作业的自定义服务:
MyCustomVm
,则服务在同一程序集中查找MyCustom.xaml
。_RibbonTabKey
结尾。视图模型成为找到的资源的数据上下文。假设该资源至少为FrameworkElement
。RibbonTabsUI
集合中。功能区绑定到XAML中的RibbonTabsUI
以用于主机应用程序:
<r:Ribbon x:Name="ribbon" Grid.Row="0" ItemsSource="{Binding RibbonTabsUI}">
<!-- other content -->
</r:Ribbon>
功能区选项卡示例如下所示:
<r:RibbonTab x:Key="MyCustom_RibbonTabKey" x:Shared="False">
<r:RibbonGroup Header="Some group">
<!-- other content -->
</r:RibbonGroup>
<!-- other content -->
</r:RibbonTab>
ApplicationMenuItems
和QuickAccessToolbarItems
的处理方式相同,不同之处在于资源键后缀。