Как объединить механизм событий RibbonControlLibrary Ribbon для работы с TabControl?

Я использую Microsofts RibbonControlLibrary для Ribbonmenu с несколькими RibbonCommands. У меня есть TabControl, который должен содержать вкладки для каждой нажатой кнопки ленты. Например, я нажимаю на RibbonCommand 2, я хочу, чтобы была создана вкладка под названием "Tab2", если она еще не присутствует в TabControl, в противном случае она должна быть сфокусирована.

Я уже реализовал http://www.codeproject.com/KB/WPF/WpfTabCloseButton.aspx, что очень приятно.

Я думаю, что до сих пор не совсем правильно понял механизм событий WPF. Мой код сильно адаптировал пример проекта Ribboncontrol.

Вот как я реализовал Команду:

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

Кнопка внутри RibbonControl выглядит следующим образом.

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

Теперь я хочу написать метод, который создает вкладку для каждого нажатия кнопки, где созданная вкладка содержит определенные пользовательские элементы управления. Я не знаю, как наилучшим образом реализовать отображение между CommandButtons и Tabs. Я думаю, что лучше всего использовать только один обработчик события click, а не обработчик события для каждой кнопки.Вопросы:

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#: как один ссылается на TabItems внутри TabControl? который показал мне, как запросить коллекцию Items TabControl. Это хорошая попытка или есть лучшая?

3)
Как я должен создать отображение между RibbonCommand и TabPage + Controls, которые должны отображаться. Конечно, я мог бы использовать словарь, как

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

Или WPF представляет лучший подход с этими ResourceDictionaries, который я до сих пор не понял.

1 ответ

Решение

Поскольку вы используете Command чтобы управлять вкладками, я полагаю, вы могли бы установить CommandParameter собственность каждого Button таким образом, чтобы можно было различать различные действия, которые необходимо выполнить (т. е. это может быть Enum, если вы уже знаете тип вкладок, которые вам нужно показать, или более сложный объект на случай, если такие вкладки могут быть созданы динамически).

Кстати, подпись RibbonButton_Click метод не выглядит корректным для меня, так как аргументы, передаваемые методу, должны иметь тип ExecutedRoutedEventHandler, Это позволит вам получить доступ к CommandParameter указано на Button уровень, через Parameter собственность args переменная. После кода для изменения:

1. Добавьте правильный CommandParameter на ваш RibbonButton

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

2. Измените обработчик на 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, правильный способ заключается в использовании CommandParameter определить, какое действие вы хотите выполнить (RibbonButton просто хозяин Commandне позволяет мне разрабатывать логику приложения для конкретной реализации пользовательского интерфейса).

2. Если вам действительно нужно запросить TacControl для его TabItemдети, ссылка, которую вы предоставили, конечно, путь.

3. После того, как вы определили действие, которое вам нужно выполнить, вы можете получить экземпляр TabItem вам нужно через регистр, который вы ранее создали (т.е. вы можете иметь надлежащий Dictionary используется для ассоциирования Enum значение с TabItem пример). Другой возможный способ, это использовать Tag собственность на каждого TabItem, установите его на правильный Enum значение и используйте следующий метод для получения правильного TabItem (Обратите внимание, что kind переменная, определенная в предыдущем фрагменте):

TabItem matchingItem = tab_main.Items.Cast<TabItem>()
                                     .Where(item => item.Tag == kind)
                                     .FirstOrDefault();
Другие вопросы по тегам