2010-07-11 6 views
2

J'utilise le Microsofts RibbonControlLibrary pour un menu Ruban avec plusieurs RibbonCommands. J'ai un TabControl qui devrait contenir des onglets pour chaque bouton de ruban pressé. Par exemple. Je clique sur RibbonCommand 2, je veux qu'un onglet appelé "Tab2" soit créé, s'il n'est pas déjà présent dans le TabControl, sinon il devrait être focalisé.Comment combiner le mécanisme d'événement RibbonControlLibrary Ribbon pour qu'il fonctionne avec un TabControl?

J'ai déjà implémenté http://www.codeproject.com/KB/WPF/WpfTabCloseButton.aspx, ce qui est très agréable.

Je pense que je ne comprends toujours pas le mécanisme d'événement de WPF. Mon code a fortement adapté le projet d'échantillon du Ribboncontrol.

Voilà comment je mis en œuvre le commandement:

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

Le bouton à l'intérieur du RibbonControl ressemble à ce qui suit.

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

AppCommands.cs

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

ResourceDictionary:

<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> 

Ce que je veux maintenant écrire est une méthode qui crée un onglet pour chaque bouton clic, alors que le tabpage créé contient commandes userc spécifiques. Je ne sais pas, comment mieux implémenter le mappage entre CommandButtons et les onglets. Je pense qu'il est préférable d'utiliser un seul gestionnaire d'événements click plutôt qu'un eventhandler pour chaque bouton. Questions:

1) Comment puis-je savoir quel bouton unique, a déclenché l'événement? J'ai seulement réussi à obtenir l'information dans le ResourceDictionary. Malheureusement, il n'y a pas de propriété comme uniqueID ou quelque chose comme ça. Je l'ai fait avec:

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

Je ne veux pas créer un mappage basé sur une propriété comme LabelTitle qui est censé pour l'affichage.

2) J'ai trouvé ce WPF/C#: How does one reference TabItems inside a TabControl? qui m'a montré comment interroger la collection Items du TabControl. Est-ce une bonne tentative ou y en a-t-il une meilleure?

3)
Comment dois-je créer le mappage entre le RibbonCommand et TabPage + Les contrôles qui doivent être affichés. Bien sûr, je pourrais utiliser un dictionnaire comme

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

Ou est-WPF présente une meilleure approche avec ces ResourceDictionaries, que je ne l'ai pas compris jusqu'à présent.

Répondre

2

Puisque vous utilisez un Command pour gérer les onglets, je suppose que vous pouvez définir la propriété CommandParameter de chaque Button de manière significative, de sorte qu'il est possible de discriminer entre les différentes actions dont vous avez besoin pour réaliser (il pourrait être un Enum, si vous connaissez déjà le type d'onglet que vous devez exposer, ou un objet plus complexe dans le cas où de tels onglets peuvent être créés dynamiquement).D'ailleurs, la signature de la méthode RibbonButton_Click ne me semble pas correcte, puisque les arguments passés à la méthode devraient être de type ExecutedRoutedEventHandler. Cela vous permettra d'accéder au CommandParameter spécifié au niveau Button, via la propriété Parameter de la variable args. Après le code à modifier:

1. Ajouter un CommandParameter approprié à votre RibbonButton

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

2. Modifier le gestionnaire à l'événement Execute, pour correspondre à une signature en bonne et gérer la paramètre en fonction de vos besoins

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; 
     } 
    } 
} 

Pour répondre directement à vos questions:

1. Vous ne devriez pas besoin de savoir quelle instance du bouton a soulevé la Command, la bonne façon est d'utiliser un CommandParameter pour identifier quel type d'action que vous souhaitez effectuer (le RibbonButton est juste l'hôte de le Command, ne me fait pas sens de concevoir la logique de l'application à l'implémentation spécifique de l'interface utilisateur).

2. Si vous avez vraiment besoin d'interroger le TacControl pour ses TabItem enfants, le lien que vous avez fourni est bien sûr la voie à suivre.

3. Une fois que vous avez identifié l'action que vous devez effectuer, vous pouvez récupérer l'instance du TabItem dont vous avez besoin à travers un registre que vous précédemment créé (vous pouvez avoir un bon Dictionary utilisé pour associer la valeur Enum avec une instance TabItem). Une autre façon possible, est d'utiliser la propriété Tag sur chaque TabItem, réglez-le sur une valeur Enum appropriée et utiliser la méthode suivante pour récupérer la TabItem appropriée (notez que kind est la variable définie dans l'extrait précédent):

TabItem matchingItem = tab_main.Items.Cast<TabItem>() 
            .Where(item => item.Tag == kind) 
            .FirstOrDefault(); 
Questions connexes