Browse Source

added new DropDownButton control

pull/1645/head
brianlagunas_cp 15 years ago
parent
commit
8f286ab983
  1. 287
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DropDownButton/Implementation/DropDownButton.cs
  2. 81
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DropDownButton/Themes/Generic.xaml
  3. 3
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml
  4. 5
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj

287
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DropDownButton/Implementation/DropDownButton.cs

@ -0,0 +1,287 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Controls.Primitives;
namespace Microsoft.Windows.Controls
{
public class DropDownButton : ContentControl, ICommandSource
{
#region Members
ToggleButton _dropDownButton;
#endregion //Members
#region Constructors
static DropDownButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DropDownButton), new FrameworkPropertyMetadata(typeof(DropDownButton)));
}
public DropDownButton()
{
Keyboard.AddKeyDownHandler(this, OnKeyDown);
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement);
}
#endregion //Constructors
#region Properties
#region DropDownContent
public static readonly DependencyProperty DropDownContentProperty = DependencyProperty.Register("DropDownContent", typeof(object), typeof(DropDownButton), new UIPropertyMetadata(null, OnDropDownContentChanged));
public object DropDownContent
{
get { return (object)GetValue(DropDownContentProperty); }
set { SetValue(DropDownContentProperty, value); }
}
private static void OnDropDownContentChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
DropDownButton dropDownButton = o as DropDownButton;
if (dropDownButton != null)
dropDownButton.OnDropDownContentChanged((object)e.OldValue, (object)e.NewValue);
}
protected virtual void OnDropDownContentChanged(object oldValue, object newValue)
{
// TODO: Add your property changed side-effects. Descendants can override as well.
}
#endregion //DropDownContent
#region IsOpen
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(DropDownButton), new UIPropertyMetadata(false, OnIsOpenChanged));
public bool IsOpen
{
get { return (bool)GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}
private static void OnIsOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
DropDownButton dropDownButton = o as DropDownButton;
if (dropDownButton != null)
dropDownButton.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue);
}
protected virtual void OnIsOpenChanged(bool oldValue, bool newValue)
{
if (newValue)
RaiseRoutedEvent(DropDownButton.OpenedEvent);
else
RaiseRoutedEvent(DropDownButton.ClosedEvent);
}
#endregion //IsOpen
#endregion //Properties
#region Base Class Overrides
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (_dropDownButton != null)
_dropDownButton.Click -= DropDownButton_Click;
_dropDownButton = GetTemplateChild("PART_DropDownButton") as ToggleButton;
if (_dropDownButton != null)
_dropDownButton.Click += DropDownButton_Click;
}
#endregion //Base Class Overrides
#region Events
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DropDownButton));
public event RoutedEventHandler Click
{
add { AddHandler(ClickEvent, value); }
remove { RemoveHandler(ClickEvent, value); }
}
public static readonly RoutedEvent OpenedEvent = EventManager.RegisterRoutedEvent("Opened", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DropDownButton));
public event RoutedEventHandler Opened
{
add { AddHandler(OpenedEvent, value); }
remove { RemoveHandler(OpenedEvent, value); }
}
public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent("Closed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DropDownButton));
public event RoutedEventHandler Closed
{
add { AddHandler(ClosedEvent, value); }
remove { RemoveHandler(ClosedEvent, value); }
}
#endregion //Events
#region Event Handlers
private void OnKeyDown(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Escape:
{
CloseDropDown();
break;
}
}
}
private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e)
{
CloseDropDown();
}
private void DropDownButton_Click(object sender, RoutedEventArgs e)
{
OnClick();
}
void CanExecuteChanged(object sender, EventArgs e)
{
if (Command != null)
{
RoutedCommand command = Command as RoutedCommand;
// If a RoutedCommand.
if (command != null)
IsEnabled = command.CanExecute(CommandParameter, CommandTarget) ? true : false;
// If a not RoutedCommand.
else
IsEnabled = Command.CanExecute(CommandParameter) ? true : false;
}
}
#endregion //Event Handlers
#region Methods
/// <summary>
/// Closes the drop down.
/// </summary>
private void CloseDropDown()
{
if (IsOpen)
IsOpen = false;
ReleaseMouseCapture();
}
protected virtual void OnClick()
{
RaiseRoutedEvent(DropDownButton.ClickEvent);
RaiseCommand();
}
/// <summary>
/// Raises routed events.
/// </summary>
private void RaiseRoutedEvent(RoutedEvent routedEvent)
{
RoutedEventArgs args = new RoutedEventArgs(routedEvent, this);
RaiseEvent(args);
}
/// <summary>
/// Raises the command's Execute event.
/// </summary>
private void RaiseCommand()
{
if (Command != null)
{
RoutedCommand routedCommand = Command as RoutedCommand;
if (routedCommand == null)
((ICommand)Command).Execute(CommandParameter);
else
routedCommand.Execute(CommandParameter, CommandTarget);
}
}
/// <summary>
/// Unhooks a command from the Command property.
/// </summary>
/// <param name="oldCommand">The old command.</param>
/// <param name="newCommand">The new command.</param>
private void UnhookCommand(ICommand oldCommand, ICommand newCommand)
{
EventHandler handler = CanExecuteChanged;
oldCommand.CanExecuteChanged -= handler;
}
/// <summary>
/// Hooks up a command to the CanExecuteChnaged event handler.
/// </summary>
/// <param name="oldCommand">The old command.</param>
/// <param name="newCommand">The new command.</param>
private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
{
EventHandler handler = new EventHandler(CanExecuteChanged);
canExecuteChangedHandler = handler;
if (newCommand != null)
newCommand.CanExecuteChanged += canExecuteChangedHandler;
}
#endregion //Methods
#region ICommandSource Members
// Keeps a copy of the CanExecuteChnaged handler so it doesn't get garbage collected.
private EventHandler canExecuteChangedHandler;
#region Command
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(DropDownButton), new PropertyMetadata((ICommand)null, OnCommandChanged));
[TypeConverter(typeof(CommandConverter))]
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DropDownButton dropDownButton = d as DropDownButton;
if (dropDownButton != null)
dropDownButton.OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue);
}
protected virtual void OnCommandChanged(ICommand oldValue, ICommand newValue)
{
// If old command is not null, then we need to remove the handlers.
if (oldValue != null)
UnhookCommand(oldValue, newValue);
HookUpCommand(oldValue, newValue);
}
#endregion //Command
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(DropDownButton), new PropertyMetadata(null));
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(DropDownButton), new PropertyMetadata(null));
public IInputElement CommandTarget
{
get { return (IInputElement)GetValue(CommandTargetProperty); }
set { SetValue(CommandTargetProperty, value); }
}
#endregion //ICommandSource Members
}
}

81
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DropDownButton/Themes/Generic.xaml

@ -0,0 +1,81 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes"
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"
xmlns:local="clr-namespace:Microsoft.Windows.Controls" >
<coreConverters:InverseBoolConverter x:Key="InverseBoolConverter" />
<LinearGradientBrush x:Key="PopupDarkBorderBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="PopupBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0" Color="#FFffffff"/>
<GradientStop Offset="1" Color="#FFE8EBED"/>
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style TargetType="{x:Type local:DropDownButton}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DropDownButton}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="True">
<ToggleButton x:Name="PART_DropDownButton" Grid.Column="1" IsTabStop="False"
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" >
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter />
</ControlTemplate>
</ToggleButton.Template>
<Grid>
<chrome:ButtonChrome x:Name="ToggleButtonChrome"
RenderChecked="{TemplateBinding IsOpen}"
RenderEnabled="{TemplateBinding IsEnabled}"
RenderMouseOver="{Binding IsMouseOver, ElementName=PART_DropDownButton}"
RenderPressed="{Binding IsPressed, ElementName=PART_DropDownButton}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="true" />
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Margin="4,3,4,3" Grid.Column="1">
<Path Width="7" Height="4" Data="M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z" Fill="#FF000000"/>
</Grid>
</Grid>
</Grid>
</ToggleButton>
<Popup x:Name="PART_Popup"
HorizontalOffset="1"
VerticalOffset="1"
AllowsTransparency="True"
StaysOpen="False"
Placement="Bottom"
Focusable="False"
IsOpen="{Binding IsChecked, ElementName=PART_DropDownButton}">
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource PopupDarkBorderBrush}" >
<ContentPresenter Content="{TemplateBinding DropDownContent}" />
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

3
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml

@ -9,7 +9,8 @@
<ResourceDictionary Source="/WPFToolkit.Extended;component/CheckListBox/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ChildWindow/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ColorCanvas/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ColorPicker/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/ColorPicker/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/DropDownButton/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/Magnifier/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/MessageBox/Themes/Generic.xaml" />
<ResourceDictionary Source="/WPFToolkit.Extended;component/DateTimeUpDown/Themes/Generic.xaml" />

5
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj

@ -103,6 +103,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="DropDownButton\Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Magnifier\Themes\Generic.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -180,6 +184,7 @@
<Compile Include="DateTimeUpDown\Implementation\DateTimePart.cs" />
<Compile Include="DateTimeUpDown\Implementation\DateTimeUpDown.cs" />
<Compile Include="DateTimeUpDown\Implementation\DateTimeParser.cs" />
<Compile Include="DropDownButton\Implementation\DropDownButton.cs" />
<Compile Include="NumericUpDown\Implementation\DecimalUpDown.cs" />
<Compile Include="NumericUpDown\Implementation\DoubleUpDown.cs" />
<Compile Include="NumericUpDown\Implementation\IntegerUpDown.cs" />

Loading…
Cancel
Save