Initial commit

This commit is contained in:
2014-04-30 17:33:21 -04:00
commit f965f46fb3
33 changed files with 2949 additions and 0 deletions

View File

@@ -0,0 +1,150 @@
// --------------------------------
// Copyright (c) Huy Pham. All rights reserved.
// This source code is made available under the terms of the Microsoft Public License (Ms-PL)
// http://www.opensource.org/licenses/ms-pl.html
// ---------------------------------
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
namespace Common.Wpf.Toolbar.SplitButton
{
[TemplatePart(Name = "PART_Button", Type = typeof(ButtonBase))]
public class SplitButton : ToggleButton
{
#region Dependency Properties
public static readonly DependencyProperty DropDownContextMenuProperty = DependencyProperty.Register("DropDownContextMenu", typeof(ContextMenu), typeof(SplitButton), new UIPropertyMetadata(null));
public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(SplitButton));
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(SplitButton));
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(UIElement), typeof(SplitButton));
public static readonly DependencyProperty MainButtonCommandProperty = DependencyProperty.Register("MainButtonCommand", typeof(ICommand), typeof(SplitButton), new FrameworkPropertyMetadata(null));
public static readonly DependencyProperty DropDownButtonCommandProperty = DependencyProperty.Register("DropDownButtonCommand", typeof(ICommand), typeof(SplitButton), new FrameworkPropertyMetadata(null));
#endregion
#region Constructors
public SplitButton()
{
// Bind the ToogleButton.IsChecked property to the drop-down's IsOpen property
var binding = new Binding("DropDownContextMenu.IsOpen") { Source = this };
SetBinding(IsCheckedProperty, binding);
Loaded += HandleSplitButtonLoaded;
}
void HandleSplitButtonLoaded(object sender, RoutedEventArgs e)
{
if (Parent is ToolBar)
{
Style style = (Style) TryFindResource("ToolBarSplitButtonStyle");
if (style != null)
Style = style;
}
Loaded -= HandleSplitButtonLoaded;
}
#endregion
#region Properties
public ContextMenu DropDownContextMenu
{
get { return GetValue(DropDownContextMenuProperty) as ContextMenu; }
set { SetValue(DropDownContextMenuProperty, value); }
}
public ImageSource Image
{
get { return GetValue(ImageProperty) as ImageSource; }
set { SetValue(ImageProperty, value); }
}
public string Text
{
get { return GetValue(TextProperty) as string; }
set { SetValue(TextProperty, value); }
}
public UIElement Target
{
get { return GetValue(TargetProperty) as UIElement; }
set { SetValue(TargetProperty, value); }
}
public ICommand MainButtonCommand
{
get { return GetValue(MainButtonCommandProperty) as ICommand; }
set { SetValue(MainButtonCommandProperty, value); }
}
public ICommand DropDownButtonCommand
{
get { return GetValue(DropDownButtonCommandProperty) as ICommand; }
set { SetValue(DropDownButtonCommandProperty, value); }
}
#endregion
#region Public Override Methods
/// <summary>
///
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
SetMainButtonCommand();
}
#endregion
#region Protected Override Methods
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == MainButtonCommandProperty)
SetMainButtonCommand();
if (e.Property == DropDownButtonCommandProperty)
Command = DropDownButtonCommand;
}
protected override void OnClick()
{
if (DropDownContextMenu == null) return;
if (DropDownButtonCommand != null)
DropDownButtonCommand.Execute(null);
// If there is a drop-down assigned to this button, then position and display it
DropDownContextMenu.PlacementTarget = this;
DropDownContextMenu.Placement = PlacementMode.Bottom;
DropDownContextMenu.IsOpen = !DropDownContextMenu.IsOpen;
}
#endregion
#region Private Methods
private void SetMainButtonCommand()
{
// Set up the event handlers
if (Template != null)
{
var button = Template.FindName("PART_Button", this) as ButtonBase;
if (button != null) button.Command = MainButtonCommand;
}
}
#endregion
}
}

View File

@@ -0,0 +1,277 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrl="clr-namespace:Common.Wpf.Toolbar.SplitButton"
xmlns:themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna">
<!-- Used for Checkmark, Radio button, TreeViewItem, Expander ToggleButton glyphs -->
<SolidColorBrush x:Key="GlyphBrush" Color="#444"/>
<!-- SelectedBackgroundBrush is used for the Selected item in ListBoxItem, ComboBoxItem-->
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD"/>
<!-- Disabled Brushes are used for the Disabled look of each control -->
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888"/>
<!-- NormalBrush is used as the Background for SimpleButton, SimpleRepeatButton -->
<LinearGradientBrush x:Key="NormalBrush" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EEE" Offset="0.0"/>
<GradientStop Color="#CCC" Offset="1.0"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="NormalBorderBrush" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#CCC" Offset="0.0"/>
<GradientStop Color="#444" Offset="1.0"/>
</LinearGradientBrush>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Margin="3" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackgroundFill" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FFF0F0EA" Offset="0.9"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonBorder" Color="#FF003C74"/>
<Style x:Key="MainButtonStyle" TargetType="{x:Type Button}" BasedOn="{x:Null}">
<Setter Property="Margin" Value="-2,-2,0,-2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="rect" Fill="Transparent" Stroke="#00000000" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="rect" Value="#00FFFFFF"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="rect" Value="#E3E3DC"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ctrl:SplitButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackgroundFill}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonBorder}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="MinHeight" Value="22" />
<Setter Property="MinWidth" Value="80" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:SplitButton}">
<themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="True" BorderBrush="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" ThemeColor="NormalColor">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Name="PART_Button" Grid.Column="0" Style="{DynamicResource MainButtonStyle}">
<StackPanel Orientation="Horizontal">
<Image x:Name="icon" Margin="4,0,2,0" VerticalAlignment="Center" Width="16" Height="16" Source="{TemplateBinding Image}" />
<Label Content="{TemplateBinding Text}" Target="{TemplateBinding Target}" VerticalAlignment="Center" Padding="0" Margin="0,0,3,0" Foreground="{TemplateBinding Foreground}"/>
</StackPanel>
</Button>
<Border x:Name="line" Grid.Column="1" Visibility="Visible" BorderThickness="1,0,0,0" BorderBrush="#3F6C96" Margin="0,-2,0,-2"/>
<Border x:Name="lineGrey" Grid.Column="2" Visibility="Visible" BorderThickness="1,0,0,0" BorderBrush="#B9CADA" Margin="0,-2,0,-2"/>
<Path Grid.Column="3" Fill="{DynamicResource GlyphBrush}" Data="M 0 0 L 4 4 L 8 0 Z" Height="5" Margin="3,2,2,0"/>
</Grid>
</themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="True"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="RenderPressed" TargetName="Chrome" Value="True"/>
<Setter Property="Visibility" Value="Hidden" TargetName="line"/>
<Setter Property="Visibility" Value="Hidden" TargetName="lineGrey"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Visibility" Value="Hidden" TargetName="line"/>
<Setter Property="Visibility" Value="Hidden" TargetName="lineGrey"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="#00FFFFFF"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Bd" SnapsToDevicePixels="True" Background="{TemplateBinding Background}">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="Bd" Value="#FF98B5E2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ToolBarSplitButtonStyle" TargetType="{x:Type ctrl:SplitButton}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1,1,1,1"/>
<Setter Property="Background" Value="#00FFFFFF"/>
<Setter Property="BorderBrush" Value="#00FFFFFF"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:SplitButton}">
<Border SnapsToDevicePixels="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel Orientation="Horizontal">
<Button x:Name="PART_Button" Style="{DynamicResource ButtonStyle}">
<StackPanel Orientation="Horizontal">
<Image Margin="2,2,2,2" VerticalAlignment="Center" Width="16" Height="16" Source="{TemplateBinding Image}"/>
<Label Content="{TemplateBinding Text}" Target="{TemplateBinding Target}" VerticalAlignment="Center" Padding="0" Margin="0,0,3,0"/>
</StackPanel>
</Button>
<Border x:Name="line" Visibility="Hidden" BorderThickness="1,0,0,0" BorderBrush="{TemplateBinding BorderBrush}" />
<Path Fill="{DynamicResource GlyphBrush}" Data="M 0 0 L 4 4 L 8 0 Z" Height="5" Margin="2,2,2,0"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="BorderBrush" Value="#FF316AC5"/>
<Setter Property="Background" Value="#FFE1E6E8"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#FF316AC5"/>
<Setter Property="Background" Value="#FFC1D2EE"/>
<Setter Property="Visibility" Value="Visible" TargetName="line"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="BorderBrush" Value="#FF316AC5"/>
<Setter Property="Background" Value="#FFC1D2EE"/>
<Setter Property="Visibility" Value="Visible" TargetName="line"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="#FF4B4B6F"/>
<Setter Property="Background" Value="#FF98B5E2"/>
<Setter Property="Visibility" Value="Visible" TargetName="line"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsKeyboardFocused" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="#FF4B4B6F"/>
<Setter Property="Background" Value="#FF98B5E2"/>
<Setter Property="Visibility" Value="Visible" TargetName="line"/>
</MultiTrigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderBrush" Value="#FF4B4B6F"/>
<Setter Property="Background" Value="#FF98B5E2"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="SplitMenuIconStyle">
<Image Source="{Binding XPath=.}"></Image>
</DataTemplate>
<ControlTemplate x:Key="SplitMenuItemTemplate" TargetType="MenuItem">
<Border Name="Border">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut"/>
<ColumnDefinition Width="13"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon"
ContentTemplate="{StaticResource SplitMenuIconStyle}"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon"
Height="16" Width="16"/>
<Border x:Name="Check"
Width="13" Height="13"
Visibility="Collapsed"
Margin="6,0,6,0"
Background="{StaticResource NormalBrush}"
BorderThickness="1"
BorderBrush="{StaticResource NormalBorderBrush}">
<Path x:Name="CheckMark"
Width="7" Height="7"
Visibility="Hidden"
SnapsToDevicePixels="False"
Stroke="{StaticResource GlyphBrush}"
StrokeThickness="2"
Data="M 0 0 L 7 7 M 0 7 L 7 0" />
</Border>
<ContentPresenter x:Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True"
Margin="5,2,0,2"
VerticalAlignment="Center"/>
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,0,2"
DockPanel.Dock="Right" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="CheckMark" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsCheckable" Value="true">
<Setter TargetName="Check" Property="Visibility" Value="Visible"/>
<Setter TargetName="Icon" Property="Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ResourceDictionary>