2

我将 Microsoft 的 RibbonControlLibrary 用于带有多个 RibbonCommands 的 Ribbonmenu。我有一个 TabControl,它应该包含每个按下的功能区按钮的选项卡。例如,我单击 RibbonCommand 2,我希望创建一个名为“Tab2”的选项卡,如果它尚未出现在 TabControl 中,否则它应该被聚焦。

我已经实现了http://www.codeproject.com/KB/WPF/WpfTabClos​​eButton.aspx,非常好。

我想我仍然没有完全正确地理解 WPF 的事件机制。我的代码强烈适应了 Ribboncontrol 的示例项目。

这就是我实现命令的方式:

<Window.CommandBindings>
  <CommandBinding Command="me:AppCommands.Protokoll" Executed="RibbonButton_Click" /> 
</Window.CommandBindings>

RibbonControl 内的按钮如下所示。

<r:RibbonButton Command="me:AppCommands.Protokoll" />

应用命令.cs

public class AppCommands
{
  public static RibbonCommand Protokoll
  {
     get { return (RibbonCommand)Application.Current.Resources["ProtokollCommand"]; }
   }
}

资源字典:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary">
    <r:RibbonCommand x:Key="ProtokollCommand"                
        LabelTitle="foo"
        ToolTipTitle="foo"
        ToolTipDescription="foo" />
</ResourceDictionary>

我现在要编写的是一个方法,它为每个按钮单击创建一个选项卡,其中创建的选项卡页包含特定的用户控件。我不知道,如何最好地实现 CommandButtons 和 Tabs 之间的映射。我认为最好只使用一个单击事件处理程序而不是每个按钮的事件处理程序。 问题:

1)我怎样才能找出哪个独特的按钮引发了事件?我只设法在 ResourceDictionary 中获取信息。不幸的是,没有诸如 uniqueID 之类的属性。我已经这样做了:

private void RibbonButton_Click(object sender, RoutedEventArgs e)
{
  // ((Microsoft.Windows.Controls.Ribbon.RibbonCommand)(((System.Windows.Controls.Button)(e.OriginalSource)).Command))
}

我不想基于应该显示的 LabelTitle 之类的属性创建映射。

2) 我发现了这个WPF/C#:如何在 TabControl 中引用 TabItems?它向我展示了如何查询 TabControl 的 Items 集合。这是一个好的尝试还是有更好的尝试?

3)
我应该如何创建应该显示的 RibbonCommand 和 TabPage + 控件之间的映射。当然我可以使用像

Dictionary<String, fooContainer>
// ...
public class fooContainer()
{
  public String TabHeaderString {get;set;}
 // other properties
}

或者 WPF 是否为这些 ResourceDictionaries 提供了一种更好的方法,我直到现在还没有理解。

4

1 回答 1

2

由于您使用 aCommand来管理选项卡,我想您可以以有意义的方式设置CommandParameter每个选项卡的属性Button,以便可以区分您需要实现的不同操作(即Enum,如果您已经知道,它可能是您需要公开的选项卡类型,或者更复杂的对象,以防可以动态创建此类选项卡)。

顺便说一句,该RibbonButton_Click方法的签名对我来说看起来不正确,因为传递给该方法的参数应该是 type ExecutedRoutedEventHandler。这样做将允许您通过变量的属性访问CommandParameter指定的Button级别。按照代码修改:Parameterargs

1.CommandParameter为您的RibbonButton

<r:RibbonButton Command="me:AppCommands.Protokoll" CommandParameter="TabKind.Sample1"/>
<r:RibbonButton Command="me:AppCommands.Protokoll" CommandParameter="TabKind.Sample2"/>

2.将handler改成Execute事件,匹配合适的签名,根据自己的需要处理参数

private void RibbonButton_Click(object sender, ExecutedRoutedEventArgs e)
{
  TabKind kind = (TabKind)e.Parameter;
  switch (kind)
  {
       case TabKind.Sample1:
       {
           //Do something meaningful...
           break;
       }
       case TabKind.Sample2:
       {
           //Do something meaningful...
           break;
       }
  }
}

直接回答你的问题:

1.您不需要知道按钮的哪个实例引发了Command,正确的方法是使用 aCommandParameter来确定您要执行什么样的操作(这RibbonButton只是 的主机,Command对我没有意义将应用程序的逻辑设计到具体的 UI 实现)。

2.如果你真的需要查询TacControl它的TabItem孩子,你提供的链接当然是要走的路。

3.一旦您确定了您需要执行的操作,您可以TabItem通过您之前创建的寄存器检索您需要的实例(即您可以有一个Dictionary用于将Enum值与TabItem实例相关联的属性)。另一种可能的方法是使用Tageach 上的属性TabItem,将其设置为适当的Enum值,然后使用以下方法来检索正确的值TabItem(注意,这kind是上一个片段中定义的变量):

TabItem matchingItem = tab_main.Items.Cast<TabItem>()
                                     .Where(item => item.Tag == kind)
                                     .FirstOrDefault();
于 2010-07-29T08:05:25.540 回答