views:

98

answers:

2

Maybe the obvious answer is that I need to use a UserControl but I'd like to know if this is possible.

I want to customize a ComboBox to display an additional button. I've been able to create a template that renders the button next to the built-in drop down button. Now, how can I wire the Click event or access any of its properties (for example IsEnabled).

A: 

You don't need a UserControl, but you do have to inherit from ComboBox to extend it. You would write something like this:

[TemplatePart(Name = "PART_ExtraButton", Type = typeof(Button))]
public class ExtendedComboBox: ComboBox {

    private Button extraButton = new Button();
    public Button ExtraButton { get { return extraButton; } private set { extraButton = value; } }

    public static readonly RoutedEvent ExtraButtonClickEvent = EventManager.RegisterRoutedEvent("ExtraButtonClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ExtendedComboBox));

    public event RoutedEventHandler ExtraButtonClick {
        add { AddHandler(ExtraButtonClickEvent, value); }
        remove { RemoveHandler(ExtraButtonClickEvent, value); }
    }

    void OnExtraButtonClick(object sender, RoutedEventArgs e) {
        RaiseEvent(new RoutedEventArgs(ExtraButtonClickEvent, this));
    }

    public bool IsExtraButtonEnabled {
        get { return (bool)GetValue(IsExtraButtonEnabledProperty); }
        set { SetValue(IsExtraButtonEnabledProperty, value); }
    }

    public static readonly DependencyProperty IsExtraButtonEnabledProperty =
        DependencyProperty.Register("IsExtraButtonEnabled", typeof(bool), typeof(ExtendedComboBox), new UIPropertyMetadata(OnIsExtraButtonEnabledChanged));

    private static void OnIsExtraButtonEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        ExtendedComboBox combo = (ExtendedComboBox)d;
        combo.ExtraButton.IsEnabled = (bool)e.NewValue;
    }

    public override void OnApplyTemplate() {
        base.OnApplyTemplate();
        var templateButton = Template.FindName("PART_ExtraButton", this) as Button;
        if(templateButton != null) {
            extraButton.Click -= OnExtraButtonClick;
            extraButton = templateButton;
            extraButton.Click += new RoutedEventHandler(OnExtraButtonClick);
            extraButton.IsEnabled = this.IsExtraButtonEnabled;
        }
    }

}
Stanislav Kniazev
Perfect answer, thanks a lot. I think I finally understand the concept.
JAG
A: 

It's sometimes possible using attached properties/events

Nir