Как объединить механизм событий RibbonControlLibrary Ribbon для работы с TabControl? - PullRequest
2 голосов
/ 11 июля 2010

Я использую библиотеку Microsofts RibbonControlLibrary для меню Ribbon с несколькими командами Ribbon.У меня есть 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 +, которые должны отображаться.Конечно, я мог бы использовать словарь, например

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

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

1 Ответ

2 голосов
/ 29 июля 2010

Поскольку вы используете 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();
...