2010-08-18 2 views
2

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

В этом случае мне нужна дополнительная кнопка на моем специальном comboBox для добавления новых записей в список элементов. Сегодня у меня это как UserControl, но оно выглядит не очень хорошо, и мне нужно больше элементов управления для моих просмотров, поэтому я начал создавать настраиваемый элемент управления, пытаясь расширить ComboBox.

Я не уедешь ... Пожалуйста, одолжите мне руку ... :)

Мой код до сих пор:

public class ComboBoxWithAdd : ComboBox 
{ 
    static ComboBoxWithAdd() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ComboBoxWithAdd), new FrameworkPropertyMetadata(typeof(ComboBoxWithAdd))); 
    } 
} 

В Generic.xaml у меня есть это:

<Style TargetType="{x:Type local:ComboBoxWithAdd}" BasedOn="{StaticResource {x:Type ComboBox}}">   
</Style> 
+0

На самом деле это звучит как хорошая ситуация для пользовательского элемента управления, а не для подкласса «ComboBox». Не могли бы вы объяснить более подробно, почему вы выбрали этот маршрут и отказаться от улучшения пользовательского контроля? Как насчет подклассификации пользовательского элемента управления? – FrustratedWithFormsDesigner

+0

@Frustrated - класс, который вы получаете от ComboBox, является настраиваемым элементом управления. Что вы советуете? –

+0

@John Bowen: К сожалению, я имею в виду настраиваемый элемент управления в смысле класса, который является подклассом 'Control', а внешний вид и макет которого обрабатываются через конструктор форм. Если я не ошибаюсь, VisualStudio обычно вызывает эти классы UserControls. – FrustratedWithFormsDesigner

ответ

4

При принятии решения о создании настраиваемого элемента управления вам необходимо определить, нужно ли добавлять фактическое поведение или просто пользовательский интерфейс. Просто добавить кнопку можно, просто настроив ControlTemplate. Похоже, вы хотите, чтобы кнопка вызывала действие, которое обновляло бы элементы ComboBox, которые указывали бы на то направление, в котором вы начали получать элемент управления из ComboBox. Вам нужно добавить несколько вещей на код и сторону XAML. В вашем стиле вам нужно добавить Setter для ControlTemplate и начать с копии шаблона по умолчанию для ComboBox (обычно я делаю это с Blend, но есть и другие источники). Затем вы можете добавить новую кнопку, где бы вы ни хотели ее в шаблоне.

<Style TargetType="{x:Type local:ComboBoxWithAdd}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:ComboBoxWithAdd}"> 
       ... copy of default template with your modifications 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Есть несколько различных способов подключения кнопки, но самый надежный заключается в использовании команды, которые вы можете связать в коде управления. Вы можете объявить свой собственный RoutedCommand в своем контрольном коде позже, но для начала просто используйте встроенный в него.

public ComboBoxWithAdd() 
{ 
    CommandBindings.Add(new CommandBinding(ApplicationCommands.New, NewExecutedMethod)); 
} 

Тогда в NewExecutedMethod просто добавить любую логику вы хотите сделать фактические действия, чтобы добавить элемент (вероятно, работая с элементами выпадающего списка в/ItemsSource). Чтобы подключить кнопку, просто установите Command="ApplicationCommands.New". Есть намного больше, что можно сделать с помощью настраиваемого элемента управления, но это должно заставить вас начать.

+0

Я думаю, что это лучший ответ, который я мог бы получить, но я понимаю, что шаблон ComboBox слишком сложный для моей головы в это время. Я не сдаюсь, но продолжаю с другими вещами, и попробую это снова в более позднее время. – rozon

+0

rozon, см. Мой ответ ниже. – Falcon

0

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

Пользовательский контроль нецелесообразен.

Но, если у вас есть требование как этот. Здесь мы идем: 1) Вам нужно получить элемент управления для того, что вы пытаетесь расширить. 2) Вам нужно создать шаблон по умолчанию для элемента управления. [Generic.Xaml]

Отдых - это ваша настройка. Но, одно преимущество - вы можете легко получить контроль Skinnable.

НТН

1

Rozon, Вы можете управлять COMBOBOX из кода позади, как это без создания сложного шаблона:

public class CustomComboBox : ComboBox 
{ 
    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     Grid grid = WpfHelper.FindAllChildrenByName<Grid>(this, "MainGrid").SingleOrDefault() as Grid; 
     if (grid != null) 
     { 
      grid.ColumnDefinitions.Add(new ColumnDefinition()); 
      Button button = new Button(); 
      button.Content = "test"; 
      button.SetValue(Grid.ColumnProperty, 2); 
      grid.Children.Add(button); 
     } 
    } 
} 

WpfHelper это просто класс, который находит визуальный ребенок от его имени.Обратите внимание, что это может легко нарушиться, если стандартный шаблон управления combobox будет изменен и MainGrid будет переименован.

+0

Прохладный. До сих пор я не знал WpfHelper. Я вижу, как это легко может сломаться, но я также могу придумать несколько других применений для этой функции. Благодаря! :) – rozon

+1

Я думаю, вы также можете сделать «var grid = GetTemplateChild (« MainGrid ») как Grid;' если у вас нет доступа к WpfHelper. –