|
using System; |
|
using System.Windows; |
|
using System.Windows.Controls; |
|
using System.Windows.Controls.Primitives; |
|
using System.Windows.Input; |
|
|
|
namespace WpfApplication1 |
|
{ |
|
[TemplatePart(Name = PART_ContentPresenter, Type = typeof(ContentPresenter))] |
|
[TemplatePart(Name = PART_DropDownButton, Type = typeof(ToggleButton))] |
|
[TemplatePart(Name = PART_Popup, Type = typeof(Popup))] |
|
internal class DropDownButton : ContentControl |
|
{ |
|
public static readonly DependencyProperty DropDownContentProperty = |
|
DependencyProperty.Register("DropDownContent", typeof(object), typeof(DropDownButton), new PropertyMetadata(null, OnDropDownContentPropertyChanged)); |
|
|
|
public static readonly DependencyProperty IsOpenProperty = |
|
DependencyProperty.Register("IsOpen", typeof(bool), typeof(DropDownButton), new PropertyMetadata(false, OnIsOpenPropertyChanged)); |
|
|
|
private const string PART_ContentPresenter = "PART_ContentPresenter"; |
|
private const string PART_DropDownButton = "PART_DropDownButton"; |
|
private const string PART_Popup = "PART_Popup"; |
|
|
|
private ToggleButton _button; |
|
private ContentPresenter _contentPresenter; |
|
private Popup _popup; |
|
|
|
static DropDownButton() |
|
{ |
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DropDownButton), new FrameworkPropertyMetadata(typeof(DropDownButton))); |
|
} |
|
|
|
public DropDownButton() |
|
{ |
|
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, new MouseButtonEventHandler(OnPreviewMouseDownOutsideCapturedElement)); |
|
} |
|
|
|
public object DropDownContent |
|
{ |
|
get { return (object)GetValue(DropDownContentProperty); } |
|
set { SetValue(DropDownContentProperty, value); } |
|
} |
|
|
|
public bool IsOpen |
|
{ |
|
get { return (bool)GetValue(IsOpenProperty); } |
|
set { SetValue(IsOpenProperty, value); } |
|
} |
|
|
|
protected ToggleButton Button |
|
{ |
|
get { return _button; } |
|
set |
|
{ |
|
if (_button != null) |
|
{ |
|
_button.Click -= DropDownButton_Click; |
|
} |
|
_button = value; |
|
if (_button != null) |
|
{ |
|
_button.Click += DropDownButton_Click; |
|
} |
|
} |
|
} |
|
|
|
protected Popup Popup |
|
{ |
|
get { return _popup; } |
|
set |
|
{ |
|
if (_popup != null) |
|
{ |
|
_popup.Opened -= Popup_Opened; |
|
} |
|
_popup = value; |
|
if (_popup != null) |
|
{ |
|
_popup.Opened += Popup_Opened; |
|
} |
|
} |
|
} |
|
|
|
public override void OnApplyTemplate() |
|
{ |
|
base.OnApplyTemplate(); |
|
|
|
_contentPresenter = GetTemplateChild(PART_ContentPresenter) as ContentPresenter; |
|
this.Button = GetTemplateChild(PART_DropDownButton) as ToggleButton; |
|
this.Popup = GetTemplateChild(PART_Popup) as Popup; |
|
} |
|
|
|
private static void OnDropDownContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
|
{ |
|
var obj = d as DropDownButton; |
|
if (obj != null) |
|
{ |
|
var oldValue = e.OldValue; |
|
var newValue = e.NewValue; |
|
obj.OnDropDownContentChanged(oldValue, newValue); |
|
} |
|
} |
|
|
|
private static void OnIsOpenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
|
{ |
|
var obj = d as DropDownButton; |
|
if (obj != null) |
|
{ |
|
var oldValue = (bool)e.OldValue; |
|
var newValue = (bool)e.NewValue; |
|
obj.OnIsOpenChanged(oldValue, newValue); |
|
} |
|
} |
|
|
|
private void CloseDropDown(bool isFocusOnButton) |
|
{ |
|
if (IsOpen) |
|
{ |
|
IsOpen = false; |
|
} |
|
ReleaseMouseCapture(); |
|
if (isFocusOnButton) |
|
{ |
|
Button.Focus(); |
|
} |
|
} |
|
|
|
private void DropDownButton_Click(object sender, RoutedEventArgs e) |
|
{ |
|
OnClick(); |
|
} |
|
|
|
private void OnClick() |
|
{ |
|
} |
|
|
|
private void OnDropDownContentChanged(object oldValue, object newValue) |
|
{ |
|
} |
|
|
|
private void OnIsOpenChanged(bool oldValue, bool newValue) |
|
{ |
|
} |
|
|
|
private void OnPreviewMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) |
|
{ |
|
CloseDropDown(false); |
|
} |
|
|
|
private void Popup_Opened(object sender, EventArgs e) |
|
{ |
|
if (_contentPresenter != null) |
|
{ |
|
_contentPresenter.MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); |
|
} |
|
} |
|
} |
|
} |