@ -0,0 +1,54 @@ |
|||||
|
|
||||
|
Microsoft Visual Studio Solution File, Format Version 11.00 |
||||
|
# Visual Studio 2010 |
||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFToolkit.Extended", "Src\WPFToolkit.Extended\WPFToolkit.Extended.csproj", "{72E591D6-8F83-4D8C-8F67-9C325E623234}" |
||||
|
EndProject |
||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFToolkit.Extended.Samples", "Src\WPFToolkit.Extended.Samples\WPFToolkit.Extended.Samples.csproj", "{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}" |
||||
|
EndProject |
||||
|
Global |
||||
|
GlobalSection(TeamFoundationVersionControl) = preSolution |
||||
|
SccNumberOfProjects = 3 |
||||
|
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} |
||||
|
SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs02 |
||||
|
SccLocalPath0 = . |
||||
|
SccProjectUniqueName1 = Src\\WPFToolkit.Extended\\WPFToolkit.Extended.csproj |
||||
|
SccProjectName1 = Src/WPFToolkit.Extended |
||||
|
SccLocalPath1 = Src\\WPFToolkit.Extended |
||||
|
SccProjectUniqueName2 = Src\\WPFToolkit.Extended.Samples\\WPFToolkit.Extended.Samples.csproj |
||||
|
SccProjectName2 = Src/WPFToolkit.Extended.Samples |
||||
|
SccLocalPath2 = Src\\WPFToolkit.Extended.Samples |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
|
Debug|Any CPU = Debug|Any CPU |
||||
|
Debug|Mixed Platforms = Debug|Mixed Platforms |
||||
|
Debug|x86 = Debug|x86 |
||||
|
Release|Any CPU = Release|Any CPU |
||||
|
Release|Mixed Platforms = Release|Mixed Platforms |
||||
|
Release|x86 = Release|x86 |
||||
|
EndGlobalSection |
||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Debug|x86.ActiveCfg = Debug|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Release|Mixed Platforms.Build.0 = Release|Any CPU |
||||
|
{72E591D6-8F83-4D8C-8F67-9C325E623234}.Release|x86.ActiveCfg = Release|Any CPU |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Debug|Any CPU.ActiveCfg = Debug|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Debug|Mixed Platforms.Build.0 = Debug|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Debug|x86.ActiveCfg = Debug|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Debug|x86.Build.0 = Debug|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Release|Any CPU.ActiveCfg = Release|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Release|Mixed Platforms.ActiveCfg = Release|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Release|Mixed Platforms.Build.0 = Release|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Release|x86.ActiveCfg = Release|x86 |
||||
|
{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}.Release|x86.Build.0 = Release|x86 |
||||
|
EndGlobalSection |
||||
|
GlobalSection(SolutionProperties) = preSolution |
||||
|
HideSolutionNode = FALSE |
||||
|
EndGlobalSection |
||||
|
EndGlobal |
||||
@ -0,0 +1,10 @@ |
|||||
|
"" |
||||
|
{ |
||||
|
"FILE_VERSION" = "9237" |
||||
|
"ENLISTMENT_CHOICE" = "NEVER" |
||||
|
"PROJECT_FILE_RELATIVE_PATH" = "" |
||||
|
"NUMBER_OF_EXCLUDED_FILES" = "0" |
||||
|
"ORIGINAL_PROJECT_FILE_PATH" = "" |
||||
|
"NUMBER_OF_NESTED_PROJECTS" = "0" |
||||
|
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT" |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using Microsoft.Windows.Design.Metadata; |
||||
|
using Microsoft.Windows.Controls; |
||||
|
using Microsoft.Windows.Design.Features; |
||||
|
using System.ComponentModel; |
||||
|
|
||||
|
[assembly: ProvideMetadata(typeof(WPFToolkit.Extended.Design.MetadataStore))] |
||||
|
|
||||
|
namespace WPFToolkit.Extended.Design |
||||
|
{ |
||||
|
internal class MetadataStore : IProvideAttributeTable |
||||
|
{ |
||||
|
public AttributeTable AttributeTable |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
AttributeTableBuilder builder = new AttributeTableBuilder(); |
||||
|
|
||||
|
|
||||
|
//builder.AddCustomAttributes(typeof(NumericUpDown), new FeatureAttribute(typeof(NumericUpDownEditor)));
|
||||
|
builder.AddCustomAttributes(typeof(NumericUpDown), "Increment", |
||||
|
new DescriptionAttribute("Specifies the amount in which to increment the value."), |
||||
|
new DisplayNameAttribute("Increment")); |
||||
|
|
||||
|
builder.AddCustomAttributes(typeof(NumericUpDown), "IsEditable", |
||||
|
new DescriptionAttribute("Determines if direct entry is allowed in the text box."), |
||||
|
new DisplayNameAttribute("IsEditable")); |
||||
|
|
||||
|
builder.AddCustomAttributes(typeof(NumericUpDown), "Maximum", |
||||
|
new DescriptionAttribute("Gets/Sets the maximum allowed value."), |
||||
|
new DisplayNameAttribute("Maximum")); |
||||
|
|
||||
|
builder.AddCustomAttributes(typeof(NumericUpDown), "Minimum", |
||||
|
new DescriptionAttribute("Gets/Sets the minimum allowed value."), |
||||
|
new DisplayNameAttribute("Minimum")); |
||||
|
|
||||
|
builder.AddCustomAttributes(typeof(NumericUpDown), "Text", |
||||
|
new DescriptionAttribute("Gets/Sets the formated string representation of the value."), |
||||
|
new DisplayNameAttribute("Text")); |
||||
|
|
||||
|
builder.AddCustomAttributes(typeof(NumericUpDown), "Value", |
||||
|
new DescriptionAttribute("Gets/Sets the numeric value."), |
||||
|
new DisplayNameAttribute("Value")); |
||||
|
|
||||
|
return builder.CreateTable(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
using System.Reflection; |
||||
|
using System.Resources; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Windows; |
||||
|
|
||||
|
// General Information about an assembly is controlled through the following
|
||||
|
// set of attributes. Change these attribute values to modify the information
|
||||
|
// associated with an assembly.
|
||||
|
[assembly: AssemblyTitle("WPFToolkit.Extended.Design")] |
||||
|
[assembly: AssemblyDescription("")] |
||||
|
[assembly: AssemblyConfiguration("")] |
||||
|
[assembly: AssemblyCompany("")] |
||||
|
[assembly: AssemblyProduct("WPFToolkit.Extended.Design")] |
||||
|
[assembly: AssemblyCopyright("Copyright © 2010")] |
||||
|
[assembly: AssemblyTrademark("")] |
||||
|
[assembly: AssemblyCulture("")] |
||||
|
|
||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
|
// to COM components. If you need to access a type in this assembly from
|
||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||
|
[assembly: ComVisible(false)] |
||||
|
|
||||
|
//In order to begin building localizable applications, set
|
||||
|
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
|
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
|
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
|
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
|
//the line below to match the UICulture setting in the project file.
|
||||
|
|
||||
|
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
|
||||
|
|
||||
|
[assembly: ThemeInfo( |
||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// or application resource dictionaries)
|
||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// app, or any theme specific resource dictionaries)
|
||||
|
)] |
||||
|
|
||||
|
|
||||
|
// Version information for an assembly consists of the following four values:
|
||||
|
//
|
||||
|
// Major Version
|
||||
|
// Minor Version
|
||||
|
// Build Number
|
||||
|
// Revision
|
||||
|
//
|
||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
|
// by using the '*' as shown below:
|
||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
[assembly: AssemblyVersion("1.0.0.0")] |
||||
|
[assembly: AssemblyFileVersion("1.0.0.0")] |
||||
@ -0,0 +1,71 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.1
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace WPFToolkit.Extended.Design.Properties |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources |
||||
|
{ |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if ((resourceMan == null)) |
||||
|
{ |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WPFToolkit.Extended.Design.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set |
||||
|
{ |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,117 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
</root> |
||||
@ -0,0 +1,30 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.1
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace WPFToolkit.Extended.Design.Properties |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] |
||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase |
||||
|
{ |
||||
|
|
||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
||||
|
|
||||
|
public static Settings Default |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return defaultInstance; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
<?xml version='1.0' encoding='utf-8'?> |
||||
|
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> |
||||
|
<Profiles> |
||||
|
<Profile Name="(Default)" /> |
||||
|
</Profiles> |
||||
|
<Settings /> |
||||
|
</SettingsFile> |
||||
@ -0,0 +1,99 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
|
<ProductVersion>8.0.30703</ProductVersion> |
||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||
|
<ProjectGuid>{FA6645C6-7CA5-427C-91F2-916D9FECD76C}</ProjectGuid> |
||||
|
<OutputType>library</OutputType> |
||||
|
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
|
<RootNamespace>WPFToolkit.Extended.Design</RootNamespace> |
||||
|
<AssemblyName>WPFToolkit.Extended.Design</AssemblyName> |
||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> |
||||
|
<TargetFrameworkProfile>Client</TargetFrameworkProfile> |
||||
|
<FileAlignment>512</FileAlignment> |
||||
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
<SccProjectName>SAK</SccProjectName> |
||||
|
<SccLocalPath>SAK</SccLocalPath> |
||||
|
<SccAuxPath>SAK</SccAuxPath> |
||||
|
<SccProvider>SAK</SccProvider> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
|
<DebugSymbols>true</DebugSymbols> |
||||
|
<DebugType>full</DebugType> |
||||
|
<Optimize>false</Optimize> |
||||
|
<OutputPath>..\WPFToolkit.Extended\bin\Debug\</OutputPath> |
||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
|
<DebugType>pdbonly</DebugType> |
||||
|
<Optimize>true</Optimize> |
||||
|
<OutputPath>..\WPFToolkit.Extended\bin\Release\</OutputPath> |
||||
|
<DefineConstants>TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<Reference Include="Microsoft.Windows.Design.Extensibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> |
||||
|
<Reference Include="Microsoft.Windows.Design.Interaction, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> |
||||
|
<Reference Include="System" /> |
||||
|
<Reference Include="System.Data" /> |
||||
|
<Reference Include="System.Xml" /> |
||||
|
<Reference Include="Microsoft.CSharp" /> |
||||
|
<Reference Include="System.Core" /> |
||||
|
<Reference Include="System.Xml.Linq" /> |
||||
|
<Reference Include="System.Data.DataSetExtensions" /> |
||||
|
<Reference Include="System.Xaml"> |
||||
|
<RequiredTargetFramework>4.0</RequiredTargetFramework> |
||||
|
</Reference> |
||||
|
<Reference Include="WindowsBase" /> |
||||
|
<Reference Include="PresentationCore" /> |
||||
|
<Reference Include="PresentationFramework" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Compile Include="MetadataStore.cs" /> |
||||
|
<Compile Include="Properties\AssemblyInfo.cs"> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
<Compile Include="Properties\Resources.Designer.cs"> |
||||
|
<AutoGen>True</AutoGen> |
||||
|
<DesignTime>True</DesignTime> |
||||
|
<DependentUpon>Resources.resx</DependentUpon> |
||||
|
</Compile> |
||||
|
<Compile Include="Properties\Settings.Designer.cs"> |
||||
|
<AutoGen>True</AutoGen> |
||||
|
<DependentUpon>Settings.settings</DependentUpon> |
||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput> |
||||
|
</Compile> |
||||
|
<EmbeddedResource Include="Properties\Resources.resx"> |
||||
|
<Generator>ResXFileCodeGenerator</Generator> |
||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput> |
||||
|
</EmbeddedResource> |
||||
|
<None Include="Properties\Settings.settings"> |
||||
|
<Generator>SettingsSingleFileGenerator</Generator> |
||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput> |
||||
|
</None> |
||||
|
<AppDesigner Include="Properties\" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\WPFToolkit.Extended\WPFToolkit.Extended.csproj"> |
||||
|
<Project>{72E591D6-8F83-4D8C-8F67-9C325E623234}</Project> |
||||
|
<Name>WPFToolkit.Extended</Name> |
||||
|
</ProjectReference> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Folder Include="EditorControls\" /> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
||||
|
Other similar extension points exist, see Microsoft.Common.targets. |
||||
|
<Target Name="BeforeBuild"> |
||||
|
</Target> |
||||
|
<Target Name="AfterBuild"> |
||||
|
</Target> |
||||
|
--> |
||||
|
</Project> |
||||
@ -0,0 +1,10 @@ |
|||||
|
"" |
||||
|
{ |
||||
|
"FILE_VERSION" = "9237" |
||||
|
"ENLISTMENT_CHOICE" = "NEVER" |
||||
|
"PROJECT_FILE_RELATIVE_PATH" = "" |
||||
|
"NUMBER_OF_EXCLUDED_FILES" = "0" |
||||
|
"ORIGINAL_PROJECT_FILE_PATH" = "" |
||||
|
"NUMBER_OF_NESTED_PROJECTS" = "0" |
||||
|
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
<Application x:Class="WPFToolkit.Extended.Samples.App" |
||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
StartupUri="MainWindow.xaml"> |
||||
|
<Application.Resources> |
||||
|
|
||||
|
</Application.Resources> |
||||
|
</Application> |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Configuration; |
||||
|
using System.Data; |
||||
|
using System.Linq; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace WPFToolkit.Extended.Samples |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Interaction logic for App.xaml
|
||||
|
/// </summary>
|
||||
|
public partial class App : Application |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<Window x:Class="WPFToolkit.Extended.Samples.MainWindow" |
||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended" |
||||
|
xmlns:local="clr-namespace:WPFToolkit.Extended.Samples" |
||||
|
Title="MainWindow" Height="600" Width="250" WindowStartupLocation="CenterScreen" ForceCursor="True" |
||||
|
xmlns:sys="clr-namespace:System;assembly=mscorlib" Background="White"> |
||||
|
|
||||
|
<Window.Resources> |
||||
|
|
||||
|
</Window.Resources> |
||||
|
|
||||
|
<StackPanel> |
||||
|
|
||||
|
<extToolkit:DecimalUpDown Margin="25,5,25,5" Value="{Binding Decimal}" FormatString="{Binding Text}" Watermark="Enter Decimal" SelectAllOnGotFocus="True" /> |
||||
|
|
||||
|
<extToolkit:DoubleUpDown Margin="25,5,25,5" Value="{Binding Double}" FormatString="{Binding Text}" Watermark="Enter Double" SelectAllOnGotFocus="True" /> |
||||
|
|
||||
|
<extToolkit:IntegerUpDown Margin="25,5,25,5" Value="{Binding Integer}" FormatString="{Binding Text}" Watermark="Enter Integer" SelectAllOnGotFocus="True" /> |
||||
|
|
||||
|
<!--<extToolkit:Calculator Precision="3" ValueChanged="Calculator_ValueChanged" />--> |
||||
|
|
||||
|
<!--<extToolkit:CalculatorUpDown Watermark="Enter Value" Margin="10" />--> |
||||
|
|
||||
|
<!--<extToolkit:ColorPicker />--> |
||||
|
|
||||
|
<!--<extToolkit:ColorCanvas SelectedColorChanged="ColorCanvas_SelectedColorChanged" />--> |
||||
|
|
||||
|
<!--<extToolkit:DateTimeUpDown VerticalAlignment="Center" Margin="25" Watermark="Enter Date" Format="FullDateTime" Value="{Binding DueDate}" />--> |
||||
|
|
||||
|
<!--<extToolkit:TimePicker VerticalAlignment="Center" Margin="25" Value="{Binding DueDate}" Watermark="Enter Time" />--> |
||||
|
|
||||
|
<!--<extToolkit:DateTimePicker Margin="25" Background="White" Value="{Binding DueDate}" Watermark="Select Date" TimeWatermark="Select Time" />--> |
||||
|
|
||||
|
<!--<extToolkit:MaskedTextBox Value="{Binding Price}" Mask="00.00" Margin="25" Watermark="Enter Value" />--> |
||||
|
|
||||
|
|
||||
|
<!--<extToolkit:PropertyGrid Margin="25" SelectedObject="{Binding ElementName=_text}" Height="300" />--> |
||||
|
|
||||
|
|
||||
|
</StackPanel> |
||||
|
</Window> |
||||
@ -0,0 +1,128 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Media.Imaging; |
||||
|
using System.Windows.Navigation; |
||||
|
using System.Windows.Shapes; |
||||
|
using System.ComponentModel; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using Microsoft.Windows.Controls; |
||||
|
using System.Text.RegularExpressions; |
||||
|
using System.Diagnostics; |
||||
|
|
||||
|
namespace WPFToolkit.Extended.Samples |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Interaction logic for MainWindow.xaml
|
||||
|
/// </summary>
|
||||
|
public partial class MainWindow : Window |
||||
|
{ |
||||
|
public MainWindow() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
DataContext = new Data(); |
||||
|
Loaded += new RoutedEventHandler(MainWindow_Loaded); |
||||
|
} |
||||
|
|
||||
|
void MainWindow_Loaded(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private void Calculator_ValueChanged(object sender, RoutedPropertyChangedEventArgs<decimal?> e) |
||||
|
{ |
||||
|
Debug.WriteLine(e.NewValue.HasValue ? e.NewValue.Value.ToString() : "NULL"); |
||||
|
} |
||||
|
|
||||
|
private void ColorCanvas_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e) |
||||
|
{ |
||||
|
Debug.WriteLine(e.NewValue); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class Data : System.ComponentModel.INotifyPropertyChanged |
||||
|
{ |
||||
|
|
||||
|
protected string _Text = "C2"; |
||||
|
public string Text |
||||
|
{ |
||||
|
get { return _Text; } |
||||
|
set |
||||
|
{ |
||||
|
_Text = value; |
||||
|
NotifyPropertyChanged("Text"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private int? _integer = 5; |
||||
|
public int? Integer |
||||
|
{ |
||||
|
get { return _integer; } |
||||
|
set |
||||
|
{ |
||||
|
_integer = value; |
||||
|
NotifyPropertyChanged("Integer"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private double? _double = 5; |
||||
|
public double? Double |
||||
|
{ |
||||
|
get { return _double; } |
||||
|
set |
||||
|
{ |
||||
|
_double = value; |
||||
|
NotifyPropertyChanged("Double"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private decimal? _decimal = 5; |
||||
|
public decimal? Decimal |
||||
|
{ |
||||
|
get { return _decimal; } |
||||
|
set |
||||
|
{ |
||||
|
_decimal = value; |
||||
|
NotifyPropertyChanged("Decimal"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private DateTime? _dueDate; |
||||
|
public DateTime? DueDate |
||||
|
{ |
||||
|
get { return _dueDate; } |
||||
|
set |
||||
|
{ |
||||
|
_dueDate = value; |
||||
|
NotifyPropertyChanged("DueDate"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public Data() |
||||
|
{ |
||||
|
//Text = "testm";
|
||||
|
} |
||||
|
|
||||
|
#region PropertyChanged
|
||||
|
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; |
||||
|
|
||||
|
private void NotifyPropertyChanged(string info) |
||||
|
{ |
||||
|
if (PropertyChanged != null) |
||||
|
{ |
||||
|
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(info)); |
||||
|
} |
||||
|
} |
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
using System.Reflection; |
||||
|
using System.Resources; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Windows; |
||||
|
|
||||
|
// General Information about an assembly is controlled through the following
|
||||
|
// set of attributes. Change these attribute values to modify the information
|
||||
|
// associated with an assembly.
|
||||
|
[assembly: AssemblyTitle("WPFToolkit.Extended.Samples")] |
||||
|
[assembly: AssemblyDescription("")] |
||||
|
[assembly: AssemblyConfiguration("")] |
||||
|
[assembly: AssemblyCompany("")] |
||||
|
[assembly: AssemblyProduct("WPFToolkit.Extended.Samples")] |
||||
|
[assembly: AssemblyCopyright("Copyright © 2010")] |
||||
|
[assembly: AssemblyTrademark("")] |
||||
|
[assembly: AssemblyCulture("")] |
||||
|
|
||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
|
// to COM components. If you need to access a type in this assembly from
|
||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||
|
[assembly: ComVisible(false)] |
||||
|
|
||||
|
//In order to begin building localizable applications, set
|
||||
|
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
|
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
|
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
|
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
|
//the line below to match the UICulture setting in the project file.
|
||||
|
|
||||
|
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
|
||||
|
|
||||
|
[assembly: ThemeInfo( |
||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// or application resource dictionaries)
|
||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// app, or any theme specific resource dictionaries)
|
||||
|
)] |
||||
|
|
||||
|
|
||||
|
// Version information for an assembly consists of the following four values:
|
||||
|
//
|
||||
|
// Major Version
|
||||
|
// Minor Version
|
||||
|
// Build Number
|
||||
|
// Revision
|
||||
|
//
|
||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
|
// by using the '*' as shown below:
|
||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
[assembly: AssemblyVersion("1.0.0.0")] |
||||
|
[assembly: AssemblyFileVersion("1.0.0.0")] |
||||
@ -0,0 +1,71 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.1
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace WPFToolkit.Extended.Samples.Properties |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources |
||||
|
{ |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if ((resourceMan == null)) |
||||
|
{ |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WPFToolkit.Extended.Samples.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set |
||||
|
{ |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,117 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
</root> |
||||
@ -0,0 +1,30 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.1
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace WPFToolkit.Extended.Samples.Properties |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] |
||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase |
||||
|
{ |
||||
|
|
||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
||||
|
|
||||
|
public static Settings Default |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return defaultInstance; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
<?xml version='1.0' encoding='utf-8'?> |
||||
|
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> |
||||
|
<Profiles> |
||||
|
<Profile Name="(Default)" /> |
||||
|
</Profiles> |
||||
|
<Settings /> |
||||
|
</SettingsFile> |
||||
@ -0,0 +1,113 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> |
||||
|
<ProductVersion>8.0.30703</ProductVersion> |
||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||
|
<ProjectGuid>{47B3F3DF-FAB7-4D0A-9267-109D30BF387F}</ProjectGuid> |
||||
|
<OutputType>WinExe</OutputType> |
||||
|
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
|
<RootNamespace>WPFToolkit.Extended.Samples</RootNamespace> |
||||
|
<AssemblyName>WPFToolkit.Extended.Samples</AssemblyName> |
||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> |
||||
|
<TargetFrameworkProfile>Client</TargetFrameworkProfile> |
||||
|
<FileAlignment>512</FileAlignment> |
||||
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
<SccProjectName>SAK</SccProjectName> |
||||
|
<SccLocalPath>SAK</SccLocalPath> |
||||
|
<SccAuxPath>SAK</SccAuxPath> |
||||
|
<SccProvider>SAK</SccProvider> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> |
||||
|
<PlatformTarget>x86</PlatformTarget> |
||||
|
<DebugSymbols>true</DebugSymbols> |
||||
|
<DebugType>full</DebugType> |
||||
|
<Optimize>false</Optimize> |
||||
|
<OutputPath>bin\Debug\</OutputPath> |
||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> |
||||
|
<PlatformTarget>x86</PlatformTarget> |
||||
|
<DebugType>pdbonly</DebugType> |
||||
|
<Optimize>true</Optimize> |
||||
|
<OutputPath>bin\Release\</OutputPath> |
||||
|
<DefineConstants>TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<Reference Include="System" /> |
||||
|
<Reference Include="System.Data" /> |
||||
|
<Reference Include="System.Xml" /> |
||||
|
<Reference Include="Microsoft.CSharp" /> |
||||
|
<Reference Include="System.Core" /> |
||||
|
<Reference Include="System.Xml.Linq" /> |
||||
|
<Reference Include="System.Data.DataSetExtensions" /> |
||||
|
<Reference Include="System.Xaml"> |
||||
|
<RequiredTargetFramework>4.0</RequiredTargetFramework> |
||||
|
</Reference> |
||||
|
<Reference Include="WindowsBase" /> |
||||
|
<Reference Include="PresentationCore" /> |
||||
|
<Reference Include="PresentationFramework" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ApplicationDefinition Include="App.xaml"> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
<SubType>Designer</SubType> |
||||
|
</ApplicationDefinition> |
||||
|
<Page Include="MainWindow.xaml"> |
||||
|
<Generator>MSBuild:Compile</Generator> |
||||
|
<SubType>Designer</SubType> |
||||
|
</Page> |
||||
|
<Compile Include="App.xaml.cs"> |
||||
|
<DependentUpon>App.xaml</DependentUpon> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
<Compile Include="MainWindow.xaml.cs"> |
||||
|
<DependentUpon>MainWindow.xaml</DependentUpon> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Compile Include="Properties\AssemblyInfo.cs"> |
||||
|
<SubType>Code</SubType> |
||||
|
</Compile> |
||||
|
<Compile Include="Properties\Resources.Designer.cs"> |
||||
|
<AutoGen>True</AutoGen> |
||||
|
<DesignTime>True</DesignTime> |
||||
|
<DependentUpon>Resources.resx</DependentUpon> |
||||
|
</Compile> |
||||
|
<Compile Include="Properties\Settings.Designer.cs"> |
||||
|
<AutoGen>True</AutoGen> |
||||
|
<DependentUpon>Settings.settings</DependentUpon> |
||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput> |
||||
|
</Compile> |
||||
|
<EmbeddedResource Include="Properties\Resources.resx"> |
||||
|
<Generator>ResXFileCodeGenerator</Generator> |
||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput> |
||||
|
</EmbeddedResource> |
||||
|
<None Include="Properties\Settings.settings"> |
||||
|
<Generator>SettingsSingleFileGenerator</Generator> |
||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput> |
||||
|
</None> |
||||
|
<AppDesigner Include="Properties\" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\WPFToolkit.Extended\WPFToolkit.Extended.csproj"> |
||||
|
<Project>{72E591D6-8F83-4D8C-8F67-9C325E623234}</Project> |
||||
|
<Name>WPFToolkit.Extended</Name> |
||||
|
</ProjectReference> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
||||
|
Other similar extension points exist, see Microsoft.Common.targets. |
||||
|
<Target Name="BeforeBuild"> |
||||
|
</Target> |
||||
|
<Target Name="AfterBuild"> |
||||
|
</Target> |
||||
|
--> |
||||
|
</Project> |
||||
@ -0,0 +1,10 @@ |
|||||
|
"" |
||||
|
{ |
||||
|
"FILE_VERSION" = "9237" |
||||
|
"ENLISTMENT_CHOICE" = "NEVER" |
||||
|
"PROJECT_FILE_RELATIVE_PATH" = "" |
||||
|
"NUMBER_OF_EXCLUDED_FILES" = "0" |
||||
|
"ORIGINAL_PROJECT_FILE_PATH" = "" |
||||
|
"NUMBER_OF_NESTED_PROJECTS" = "0" |
||||
|
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" |
||||
|
} |
||||
@ -0,0 +1,266 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Shapes; |
||||
|
using System.Windows.Threading; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A control to provide a visual indicator when an application is busy.
|
||||
|
/// </summary>
|
||||
|
[TemplateVisualState(Name = VisualStates.StateIdle, GroupName = VisualStates.GroupBusyStatus)] |
||||
|
[TemplateVisualState(Name = VisualStates.StateBusy, GroupName = VisualStates.GroupBusyStatus)] |
||||
|
[TemplateVisualState(Name = VisualStates.StateVisible, GroupName = VisualStates.GroupVisibility)] |
||||
|
[TemplateVisualState(Name = VisualStates.StateHidden, GroupName = VisualStates.GroupVisibility)] |
||||
|
[StyleTypedProperty(Property = "OverlayStyle", StyleTargetType = typeof(Rectangle))] |
||||
|
[StyleTypedProperty(Property = "ProgressBarStyle", StyleTargetType = typeof(ProgressBar))] |
||||
|
public class BusyIndicator : ContentControl |
||||
|
{ |
||||
|
#region Private Members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Timer used to delay the initial display and avoid flickering.
|
||||
|
/// </summary>
|
||||
|
private DispatcherTimer _displayAfterTimer = new DispatcherTimer(); |
||||
|
|
||||
|
#endregion //Private Members
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static BusyIndicator() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(BusyIndicator), new FrameworkPropertyMetadata(typeof(BusyIndicator))); |
||||
|
} |
||||
|
|
||||
|
public BusyIndicator() |
||||
|
{ |
||||
|
_displayAfterTimer.Tick += DisplayAfterTimerElapsed; |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the OnApplyTemplate method.
|
||||
|
/// </summary>
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
ChangeVisualState(false); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the BusyContent is visible.
|
||||
|
/// </summary>
|
||||
|
protected bool IsContentVisible { get; set; } |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Dependency Properties
|
||||
|
|
||||
|
#region IsBusy
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the IsBusy dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register( |
||||
|
"IsBusy", |
||||
|
typeof(bool), |
||||
|
typeof(BusyIndicator), |
||||
|
new PropertyMetadata(false, new PropertyChangedCallback(OnIsBusyChanged))); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the busy indicator should show.
|
||||
|
/// </summary>
|
||||
|
public bool IsBusy |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsBusyProperty); } |
||||
|
set { SetValue(IsBusyProperty, value); } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IsBusyProperty property changed handler.
|
||||
|
/// </summary>
|
||||
|
/// <param name="d">BusyIndicator that changed its IsBusy.</param>
|
||||
|
/// <param name="e">Event arguments.</param>
|
||||
|
private static void OnIsBusyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
((BusyIndicator)d).OnIsBusyChanged(e); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IsBusyProperty property changed handler.
|
||||
|
/// </summary>
|
||||
|
/// <param name="e">Event arguments.</param>
|
||||
|
protected virtual void OnIsBusyChanged(DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
if (IsBusy) |
||||
|
{ |
||||
|
if (DisplayAfter.Equals(TimeSpan.Zero)) |
||||
|
{ |
||||
|
// Go visible now
|
||||
|
IsContentVisible = true; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// Set a timer to go visible
|
||||
|
_displayAfterTimer.Interval = DisplayAfter; |
||||
|
_displayAfterTimer.Start(); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
// No longer visible
|
||||
|
_displayAfterTimer.Stop(); |
||||
|
IsContentVisible = false; |
||||
|
} |
||||
|
|
||||
|
ChangeVisualState(true); |
||||
|
} |
||||
|
|
||||
|
#endregion //IsBusy
|
||||
|
|
||||
|
#region Busy Content
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the BusyContent dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty BusyContentProperty = DependencyProperty.Register( |
||||
|
"BusyContent", |
||||
|
typeof(object), |
||||
|
typeof(BusyIndicator), |
||||
|
new PropertyMetadata(null)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating the busy content to display to the user.
|
||||
|
/// </summary>
|
||||
|
public object BusyContent |
||||
|
{ |
||||
|
get { return (object)GetValue(BusyContentProperty); } |
||||
|
set { SetValue(BusyContentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Busy Content
|
||||
|
|
||||
|
#region Busy Content Template
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the BusyTemplate dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty BusyContentTemplateProperty = DependencyProperty.Register( |
||||
|
"BusyContentTemplate", |
||||
|
typeof(DataTemplate), |
||||
|
typeof(BusyIndicator), |
||||
|
new PropertyMetadata(null)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating the template to use for displaying the busy content to the user.
|
||||
|
/// </summary>
|
||||
|
public DataTemplate BusyContentTemplate |
||||
|
{ |
||||
|
get { return (DataTemplate)GetValue(BusyContentTemplateProperty); } |
||||
|
set { SetValue(BusyContentTemplateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Busy Content Template
|
||||
|
|
||||
|
#region Display After
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the DisplayAfter dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty DisplayAfterProperty = DependencyProperty.Register( |
||||
|
"DisplayAfter", |
||||
|
typeof(TimeSpan), |
||||
|
typeof(BusyIndicator), |
||||
|
new PropertyMetadata(TimeSpan.FromSeconds(0.1))); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating how long to delay before displaying the busy content.
|
||||
|
/// </summary>
|
||||
|
public TimeSpan DisplayAfter |
||||
|
{ |
||||
|
get { return (TimeSpan)GetValue(DisplayAfterProperty); } |
||||
|
set { SetValue(DisplayAfterProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Display After
|
||||
|
|
||||
|
#region Overlay Style
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the OverlayStyle dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty OverlayStyleProperty = DependencyProperty.Register( |
||||
|
"OverlayStyle", |
||||
|
typeof(Style), |
||||
|
typeof(BusyIndicator), |
||||
|
new PropertyMetadata(null)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating the style to use for the overlay.
|
||||
|
/// </summary>
|
||||
|
public Style OverlayStyle |
||||
|
{ |
||||
|
get { return (Style)GetValue(OverlayStyleProperty); } |
||||
|
set { SetValue(OverlayStyleProperty, value); } |
||||
|
} |
||||
|
#endregion //Overlay Style
|
||||
|
|
||||
|
#region ProgressBar Style
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the ProgressBarStyle dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty ProgressBarStyleProperty = DependencyProperty.Register( |
||||
|
"ProgressBarStyle", |
||||
|
typeof(Style), |
||||
|
typeof(BusyIndicator), |
||||
|
new PropertyMetadata(null)); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating the style to use for the progress bar.
|
||||
|
/// </summary>
|
||||
|
public Style ProgressBarStyle |
||||
|
{ |
||||
|
get { return (Style)GetValue(ProgressBarStyleProperty); } |
||||
|
set { SetValue(ProgressBarStyleProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ProgressBar Style
|
||||
|
|
||||
|
#endregion //Dependency Properties
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Handler for the DisplayAfterTimer.
|
||||
|
/// </summary>
|
||||
|
/// <param name="sender">Event sender.</param>
|
||||
|
/// <param name="e">Event arguments.</param>
|
||||
|
private void DisplayAfterTimerElapsed(object sender, EventArgs e) |
||||
|
{ |
||||
|
_displayAfterTimer.Stop(); |
||||
|
IsContentVisible = true; |
||||
|
ChangeVisualState(true); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Changes the control's visual state(s).
|
||||
|
/// </summary>
|
||||
|
/// <param name="useTransitions">True if state transitions should be used.</param>
|
||||
|
protected virtual void ChangeVisualState(bool useTransitions) |
||||
|
{ |
||||
|
VisualStateManager.GoToState(this, IsBusy ? VisualStates.StateBusy : VisualStates.StateIdle, useTransitions); |
||||
|
VisualStateManager.GoToState(this, IsContentVisible ? VisualStates.StateVisible : VisualStates.StateHidden, useTransitions); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
internal static partial class VisualStates |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Busyness group name.
|
||||
|
/// </summary>
|
||||
|
public const string GroupBusyStatus = "BusyStatusStates"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Busy state for BusyIndicator.
|
||||
|
/// </summary>
|
||||
|
public const string StateBusy = "Busy"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Idle state for BusyIndicator.
|
||||
|
/// </summary>
|
||||
|
public const string StateIdle = "Idle"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// BusyDisplay group.
|
||||
|
/// </summary>
|
||||
|
public const string GroupVisibility = "VisibilityStates"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Visible state name for BusyIndicator.
|
||||
|
/// </summary>
|
||||
|
public const string StateVisible = "Visible"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Hidden state name for BusyIndicator.
|
||||
|
/// </summary>
|
||||
|
public const string StateHidden = "Hidden"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,144 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:sys="clr-namespace:System;assembly=mscorlib" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls"> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- BusyIndicator --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:BusyIndicator}"> |
||||
|
<Setter Property="BusyContent" Value="Please wait..."/> |
||||
|
<Setter Property="IsTabStop" Value="False"/> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="OverlayStyle"> |
||||
|
<Setter.Value> |
||||
|
<Style TargetType="Rectangle"> |
||||
|
<Setter Property="Fill" Value="White"/> |
||||
|
<Setter Property="Opacity" Value="0.5"/> |
||||
|
</Style> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
<Setter Property="ProgressBarStyle"> |
||||
|
<Setter.Value> |
||||
|
<Style TargetType="ProgressBar"> |
||||
|
<Setter Property="IsIndeterminate" Value="True"/> |
||||
|
<Setter Property="Height" Value="15"/> |
||||
|
<Setter Property="Margin" Value="8,0,8,8"/> |
||||
|
</Style> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
<Setter Property="DisplayAfter" Value="00:00:00.1"/> |
||||
|
<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 local:BusyIndicator}"> |
||||
|
<Grid> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="VisibilityStates"> |
||||
|
<VisualState x:Name="Hidden"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.001" Storyboard.TargetName="busycontent" Storyboard.TargetProperty="(UIElement.Visibility)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Collapsed</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.001" Storyboard.TargetName="overlay" Storyboard.TargetProperty="(UIElement.Visibility)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Collapsed</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Visible"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.001" Storyboard.TargetName="busycontent" Storyboard.TargetProperty="(UIElement.Visibility)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.001" Storyboard.TargetName="overlay" Storyboard.TargetProperty="(UIElement.Visibility)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
<VisualStateGroup x:Name="BusyStatusStates"> |
||||
|
<VisualState x:Name="Idle"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.001" Storyboard.TargetName="content" Storyboard.TargetProperty="(Control.IsEnabled)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<sys:Boolean>True</sys:Boolean> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Busy"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.001" Storyboard.TargetName="content" Storyboard.TargetProperty="(Control.IsEnabled)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<sys:Boolean>False</sys:Boolean> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
<ContentControl x:Name="content" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsTabStop="False" Focusable="False"/> |
||||
|
<Rectangle x:Name="overlay" Style="{TemplateBinding OverlayStyle}"/> |
||||
|
<ContentPresenter x:Name="busycontent"> |
||||
|
<ContentPresenter.Content> |
||||
|
<Grid HorizontalAlignment="Center" VerticalAlignment="Center"> |
||||
|
<Border Background="White" BorderThickness="1" CornerRadius="2"> |
||||
|
<Border.BorderBrush> |
||||
|
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> |
||||
|
<GradientStop Color="#FFA3AEB9" Offset="0"/> |
||||
|
<GradientStop Color="#FF8399A9" Offset="0.375"/> |
||||
|
<GradientStop Color="#FF718597" Offset="0.375"/> |
||||
|
<GradientStop Color="#FF617584" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.BorderBrush> |
||||
|
<Border CornerRadius="1.5" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> |
||||
|
<GradientStop Color="#FFF6F8F9" Offset="0.02"/> |
||||
|
<GradientStop Color="#FFB8B8B8" Offset="0.996"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Grid MinWidth="150"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
<ContentPresenter Content="{TemplateBinding BusyContent}" ContentTemplate="{TemplateBinding BusyContentTemplate}" Margin="8"/> |
||||
|
<ProgressBar Grid.Row="1" Style="{TemplateBinding ProgressBarStyle}"/> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</ContentPresenter.Content> |
||||
|
</ContentPresenter> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,231 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Markup; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a spinner control that includes two Buttons.
|
||||
|
/// </summary>
|
||||
|
[ContentProperty("Content")] |
||||
|
public class ButtonSpinner : Spinner |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
#region AllowSpin
|
||||
|
|
||||
|
public static readonly DependencyProperty AllowSpinProperty = DependencyProperty.Register("AllowSpin", typeof(bool), typeof(ButtonSpinner), new UIPropertyMetadata(true)); |
||||
|
public bool AllowSpin |
||||
|
{ |
||||
|
get { return (bool)GetValue(AllowSpinProperty); } |
||||
|
set { SetValue(AllowSpinProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //AllowSpin
|
||||
|
|
||||
|
#region Content
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the Content dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(ButtonSpinner), new PropertyMetadata(null, OnContentPropertyChanged)); |
||||
|
public object Content |
||||
|
{ |
||||
|
get { return GetValue(ContentProperty) as object; } |
||||
|
set { SetValue(ContentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// ContentProperty property changed handler.
|
||||
|
/// </summary>
|
||||
|
/// <param name="d">ButtonSpinner that changed its Content.</param>
|
||||
|
/// <param name="e">Event arguments.</param>
|
||||
|
private static void OnContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonSpinner source = d as ButtonSpinner; |
||||
|
source.OnContentChanged(e.OldValue, e.NewValue); |
||||
|
} |
||||
|
|
||||
|
#endregion //Content
|
||||
|
|
||||
|
#region DecreaseButton
|
||||
|
|
||||
|
private ButtonBase _decreaseButton; |
||||
|
/// <summary>
|
||||
|
/// Gets or sets the DecreaseButton template part.
|
||||
|
/// </summary>
|
||||
|
private ButtonBase DecreaseButton |
||||
|
{ |
||||
|
get { return _decreaseButton; } |
||||
|
set |
||||
|
{ |
||||
|
if (_decreaseButton != null) |
||||
|
{ |
||||
|
_decreaseButton.Click -= OnButtonClick; |
||||
|
} |
||||
|
|
||||
|
_decreaseButton = value; |
||||
|
|
||||
|
if (_decreaseButton != null) |
||||
|
{ |
||||
|
_decreaseButton.Click += OnButtonClick; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //DecreaseButton
|
||||
|
|
||||
|
#region IncreaseButton
|
||||
|
|
||||
|
private ButtonBase _increaseButton; |
||||
|
/// <summary>
|
||||
|
/// Gets or sets the IncreaseButton template part.
|
||||
|
/// </summary>
|
||||
|
private ButtonBase IncreaseButton |
||||
|
{ |
||||
|
get { return _increaseButton; } |
||||
|
set |
||||
|
{ |
||||
|
if (_increaseButton != null) |
||||
|
{ |
||||
|
_increaseButton.Click -= OnButtonClick; |
||||
|
} |
||||
|
|
||||
|
_increaseButton = value; |
||||
|
|
||||
|
if (_increaseButton != null) |
||||
|
{ |
||||
|
_increaseButton.Click += OnButtonClick; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //IncreaseButton
|
||||
|
|
||||
|
#region ShowButtonSpinner
|
||||
|
|
||||
|
public static readonly DependencyProperty ShowButtonSpinnerProperty = DependencyProperty.Register("ShowButtonSpinner", typeof(bool), typeof(ButtonSpinner), new UIPropertyMetadata(true)); |
||||
|
public bool ShowButtonSpinner |
||||
|
{ |
||||
|
get { return (bool)GetValue(ShowButtonSpinnerProperty); } |
||||
|
set { SetValue(ShowButtonSpinnerProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ShowButtonSpinner
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static ButtonSpinner() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonSpinner), new FrameworkPropertyMetadata(typeof(ButtonSpinner))); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
IncreaseButton = GetTemplateChild("IncreaseButton") as ButtonBase; |
||||
|
DecreaseButton = GetTemplateChild("DecreaseButton") as ButtonBase; |
||||
|
|
||||
|
SetButtonUsage(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Cancel LeftMouseButtonUp events originating from a button that has
|
||||
|
/// been changed to disabled.
|
||||
|
/// </summary>
|
||||
|
/// <param name="e">The data for the event.</param>
|
||||
|
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) |
||||
|
{ |
||||
|
base.OnMouseLeftButtonUp(e); |
||||
|
|
||||
|
Point mousePosition; |
||||
|
if (IncreaseButton != null && IncreaseButton.IsEnabled == false) |
||||
|
{ |
||||
|
mousePosition = e.GetPosition(IncreaseButton); |
||||
|
if (mousePosition.X > 0 && mousePosition.X < IncreaseButton.ActualWidth && |
||||
|
mousePosition.Y > 0 && mousePosition.Y < IncreaseButton.ActualHeight) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (DecreaseButton != null && DecreaseButton.IsEnabled == false) |
||||
|
{ |
||||
|
mousePosition = e.GetPosition(DecreaseButton); |
||||
|
if (mousePosition.X > 0 && mousePosition.X < DecreaseButton.ActualWidth && |
||||
|
mousePosition.Y > 0 && mousePosition.Y < DecreaseButton.ActualHeight) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Called when valid spin direction changed.
|
||||
|
/// </summary>
|
||||
|
/// <param name="oldValue">The old value.</param>
|
||||
|
/// <param name="newValue">The new value.</param>
|
||||
|
protected override void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue) |
||||
|
{ |
||||
|
SetButtonUsage(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Handle click event of IncreaseButton and DecreaseButton template parts,
|
||||
|
/// translating Click to appropriate Spin event.
|
||||
|
/// </summary>
|
||||
|
/// <param name="sender">Event sender, should be either IncreaseButton or DecreaseButton template part.</param>
|
||||
|
/// <param name="e">Event args.</param>
|
||||
|
private void OnButtonClick(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (AllowSpin) |
||||
|
{ |
||||
|
SpinDirection direction = sender == IncreaseButton ? SpinDirection.Increase : SpinDirection.Decrease; |
||||
|
OnSpin(new SpinEventArgs(direction)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Occurs when the Content property value changed.
|
||||
|
/// </summary>
|
||||
|
/// <param name="oldValue">The old value of the Content property.</param>
|
||||
|
/// <param name="newValue">The new value of the Content property.</param>
|
||||
|
protected virtual void OnContentChanged(object oldValue, object newValue) { } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Disables or enables the buttons based on the valid spin direction.
|
||||
|
/// </summary>
|
||||
|
private void SetButtonUsage() |
||||
|
{ |
||||
|
// buttonspinner adds buttons that spin, so disable accordingly.
|
||||
|
if (IncreaseButton != null) |
||||
|
{ |
||||
|
IncreaseButton.IsEnabled = ((ValidSpinDirection & ValidSpinDirections.Increase) == ValidSpinDirections.Increase); |
||||
|
} |
||||
|
|
||||
|
if (DecreaseButton != null) |
||||
|
{ |
||||
|
DecreaseButton.IsEnabled = ((ValidSpinDirection & ValidSpinDirections.Decrease) == ValidSpinDirections.Decrease); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents spin directions that could be initiated by the end-user.
|
||||
|
/// </summary>
|
||||
|
/// <QualityBand>Preview</QualityBand>
|
||||
|
public enum SpinDirection |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a spin initiated by the end-user in order to Increase a value.
|
||||
|
/// </summary>
|
||||
|
Increase = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Represents a spin initiated by the end-user in order to Decrease a value.
|
||||
|
/// </summary>
|
||||
|
Decrease = 1 |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides data for the Spinner.Spin event.
|
||||
|
/// </summary>
|
||||
|
/// <QualityBand>Preview</QualityBand>
|
||||
|
public class SpinEventArgs : RoutedEventArgs |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the SpinDirection for the spin that has been initiated by the
|
||||
|
/// end-user.
|
||||
|
/// </summary>
|
||||
|
public SpinDirection Direction { get; private set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the SpinEventArgs class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="direction">Spin direction.</param>
|
||||
|
public SpinEventArgs(SpinDirection direction) |
||||
|
: base() |
||||
|
{ |
||||
|
Direction = direction; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Base class for controls that represents controls that can spin.
|
||||
|
/// </summary>
|
||||
|
public abstract class Spinner : Control |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Identifies the ValidSpinDirection dependency property.
|
||||
|
/// </summary>
|
||||
|
public static readonly DependencyProperty ValidSpinDirectionProperty = DependencyProperty.Register("ValidSpinDirection", typeof(ValidSpinDirections), typeof(Spinner), new PropertyMetadata(ValidSpinDirections.Increase | ValidSpinDirections.Decrease, OnValidSpinDirectionPropertyChanged)); |
||||
|
public ValidSpinDirections ValidSpinDirection |
||||
|
{ |
||||
|
get { return (ValidSpinDirections)GetValue(ValidSpinDirectionProperty); } |
||||
|
set { SetValue(ValidSpinDirectionProperty, value); } |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// ValidSpinDirectionProperty property changed handler.
|
||||
|
/// </summary>
|
||||
|
/// <param name="d">ButtonSpinner that changed its ValidSpinDirection.</param>
|
||||
|
/// <param name="e">Event arguments.</param>
|
||||
|
private static void OnValidSpinDirectionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Spinner source = (Spinner)d; |
||||
|
ValidSpinDirections oldvalue = (ValidSpinDirections)e.OldValue; |
||||
|
ValidSpinDirections newvalue = (ValidSpinDirections)e.NewValue; |
||||
|
source.OnValidSpinDirectionChanged(oldvalue, newvalue); |
||||
|
} |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Occurs when spinning is initiated by the end-user.
|
||||
|
/// </summary>
|
||||
|
public event EventHandler<SpinEventArgs> Spin; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the Spinner class.
|
||||
|
/// </summary>
|
||||
|
protected Spinner() { } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Raises the OnSpin event when spinning is initiated by the end-user.
|
||||
|
/// </summary>
|
||||
|
/// <param name="e">Spin event args.</param>
|
||||
|
protected virtual void OnSpin(SpinEventArgs e) |
||||
|
{ |
||||
|
ValidSpinDirections valid = e.Direction == SpinDirection.Increase ? ValidSpinDirections.Increase : ValidSpinDirections.Decrease; |
||||
|
|
||||
|
//Only raise the event if spin is allowed.
|
||||
|
if ((ValidSpinDirection & valid) == valid) |
||||
|
{ |
||||
|
EventHandler<SpinEventArgs> handler = Spin; |
||||
|
if (handler != null) |
||||
|
{ |
||||
|
handler(this, e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Called when valid spin direction changed.
|
||||
|
/// </summary>
|
||||
|
/// <param name="oldValue">The old value.</param>
|
||||
|
/// <param name="newValue">The new value.</param>
|
||||
|
protected virtual void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue) { } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents spin directions that are valid.
|
||||
|
/// </summary>
|
||||
|
[Flags] |
||||
|
public enum ValidSpinDirections |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Can not increase nor decrease.
|
||||
|
/// </summary>
|
||||
|
None = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Can increase.
|
||||
|
/// </summary>
|
||||
|
Increase = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Can decrease.
|
||||
|
/// </summary>
|
||||
|
Decrease = 2 |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,92 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes"> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- ButtonSpinner --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> |
||||
|
|
||||
|
<SolidColorBrush x:Key="SpinButtonGlyphNormalForegroundFillKey" Color="#FF000000" /> |
||||
|
|
||||
|
<DataTemplate x:Key="IncreaseGlyph"> |
||||
|
<Path Width="7" Height="4" Data="M 0,3 C0,3 0,4 0,4 0,4 3,4 3,4 3,4 3,3 3,3 3,3 4,3 4,3 4,3 4,4 4,4 4,4 7,4 7,4 7,4 7,3 7,3 7,3 6,3 6,3 6,3 6,2 6,2 6,2 5,2 5,2 5,2 5,1 5,1 5,1 4,1 4,1 4,1 4,0 4,0 4,0 3,0 3,0 3,0 3,1 3,1 3,1 2,1 2,1 2,1 2,2 2,2 2,2 1,2 1,2 1,2 1,3 1,3 1,3 0,3 0,3 z" Fill="{StaticResource SpinButtonGlyphNormalForegroundFillKey}"/> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<DataTemplate x:Key="DecreaseGlyph"> |
||||
|
<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="{StaticResource SpinButtonGlyphNormalForegroundFillKey}"/> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:ButtonSpinner}"> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="IsTabStop" Value="True" /> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" /> |
||||
|
<Setter Property="BorderBrush"> |
||||
|
<Setter.Value> |
||||
|
<LinearGradientBrush 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> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
<Setter Property="Background" Value="Transparent" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="VerticalContentAlignment" Value="Center" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:ButtonSpinner}"> |
||||
|
<Grid> |
||||
|
<Border x:Name="ElementContainer" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> |
||||
|
<DockPanel Focusable="False"> |
||||
|
<Grid DockPanel.Dock="Right" Visibility="{TemplateBinding ShowButtonSpinner, Converter={StaticResource BooleanToVisibilityConverter}}"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="*" /> |
||||
|
<RowDefinition Height="1" /> |
||||
|
<RowDefinition Height="*" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<RepeatButton x:Name="IncreaseButton" SnapsToDevicePixels="True" Grid.Row="0" ClickMode="Press" IsTabStop="{Binding IsTabStop, RelativeSource={RelativeSource TemplatedParent}}"> |
||||
|
<RepeatButton.Template> |
||||
|
<ControlTemplate TargetType="RepeatButton"> |
||||
|
<ContentPresenter /> |
||||
|
</ControlTemplate> |
||||
|
</RepeatButton.Template> |
||||
|
<Grid> |
||||
|
<chrome:ButtonChrome CornerRadius="0" |
||||
|
RenderEnabled="{TemplateBinding IsEnabled}" |
||||
|
RenderMouseOver="{Binding IsMouseOver, ElementName=IncreaseButton}" |
||||
|
RenderPressed="{Binding IsPressed, ElementName=IncreaseButton}"/> |
||||
|
<ContentControl ContentTemplate="{StaticResource IncreaseGlyph}" Margin="5,1" Focusable="False" /> |
||||
|
</Grid> |
||||
|
</RepeatButton> |
||||
|
<RepeatButton x:Name="DecreaseButton" SnapsToDevicePixels="True" Grid.Row="2" ClickMode="Press" IsTabStop="{Binding IsTabStop, RelativeSource={RelativeSource TemplatedParent}}" > |
||||
|
<RepeatButton.Template> |
||||
|
<ControlTemplate TargetType="RepeatButton"> |
||||
|
<ContentPresenter /> |
||||
|
</ControlTemplate> |
||||
|
</RepeatButton.Template> |
||||
|
<Grid> |
||||
|
<chrome:ButtonChrome CornerRadius="0" |
||||
|
RenderEnabled="{TemplateBinding IsEnabled}" |
||||
|
RenderMouseOver="{Binding IsMouseOver, ElementName=DecreaseButton}" |
||||
|
RenderPressed="{Binding IsPressed, ElementName=DecreaseButton}"/> |
||||
|
<ContentControl ContentTemplate="{StaticResource DecreaseGlyph}" Margin="5,1" Focusable="False" /> |
||||
|
</Grid> |
||||
|
</RepeatButton> |
||||
|
</Grid> |
||||
|
<ContentControl x:Name="presentationSite" Focusable="False" |
||||
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
||||
|
Content="{TemplateBinding Content}" /> |
||||
|
</DockPanel> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,466 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Threading; |
||||
|
using Microsoft.Windows.Controls.Core.Utilities; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class Calculator : Control |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private ContentControl _buttonPanel; |
||||
|
private readonly DispatcherTimer _timer; |
||||
|
private Button _calculatorButton; |
||||
|
|
||||
|
private bool _showNewNumber = true; |
||||
|
private decimal _previousValue; |
||||
|
private Operation _lastOperation = Operation.None; |
||||
|
private CalculatorButtonType _lastButtonPressed; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Enumerations
|
||||
|
|
||||
|
public enum CalculatorButtonType |
||||
|
{ |
||||
|
Add, |
||||
|
Back, |
||||
|
Cancel, |
||||
|
Clear, |
||||
|
Decimal, |
||||
|
Divide, |
||||
|
Eight, |
||||
|
Equal, |
||||
|
Five, |
||||
|
Four, |
||||
|
Fraction, |
||||
|
MAdd, |
||||
|
MC, |
||||
|
MR, |
||||
|
MS, |
||||
|
MSub, |
||||
|
Multiply, |
||||
|
Negate, |
||||
|
Nine, |
||||
|
None, |
||||
|
One, |
||||
|
Percent, |
||||
|
Seven, |
||||
|
Six, |
||||
|
Sqrt, |
||||
|
Subtract, |
||||
|
Three, |
||||
|
Two, |
||||
|
Zero |
||||
|
} |
||||
|
|
||||
|
public enum Operation |
||||
|
{ |
||||
|
Add, |
||||
|
Subtract, |
||||
|
Divide, |
||||
|
Multiply, |
||||
|
Percent, |
||||
|
Sqrt, |
||||
|
Fraction, |
||||
|
None, |
||||
|
Clear, |
||||
|
Negate |
||||
|
} |
||||
|
|
||||
|
#endregion //Enumerations
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
public ICommand CalculaterButtonClickCommand { get; private set; } |
||||
|
|
||||
|
#region CalculatorButtonType
|
||||
|
|
||||
|
public static readonly DependencyProperty CalculatorButtonTypeProperty = DependencyProperty.RegisterAttached("CalculatorButtonType", typeof(CalculatorButtonType), typeof(Calculator), new UIPropertyMetadata(CalculatorButtonType.None, OnCalculatorButtonTypeChanged)); |
||||
|
public static CalculatorButtonType GetCalculatorButtonType(DependencyObject target) |
||||
|
{ |
||||
|
return (CalculatorButtonType)target.GetValue(CalculatorButtonTypeProperty); |
||||
|
} |
||||
|
public static void SetCalculatorButtonType(DependencyObject target, CalculatorButtonType value) |
||||
|
{ |
||||
|
target.SetValue(CalculatorButtonTypeProperty, value); |
||||
|
} |
||||
|
private static void OnCalculatorButtonTypeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
OnCalculatorButtonTypeChanged(o, (CalculatorButtonType)e.OldValue, (CalculatorButtonType)e.NewValue); |
||||
|
} |
||||
|
private static void OnCalculatorButtonTypeChanged(DependencyObject o, CalculatorButtonType oldValue, CalculatorButtonType newValue) |
||||
|
{ |
||||
|
Button button = o as Button; |
||||
|
button.CommandParameter = newValue; |
||||
|
button.Content = CalculatorUtilities.GetCalculatorButtonContent(newValue); |
||||
|
} |
||||
|
|
||||
|
#endregion //CalculatorButtonType
|
||||
|
|
||||
|
#region DisplayText
|
||||
|
|
||||
|
public static readonly DependencyProperty DisplayTextProperty = DependencyProperty.Register("DisplayText", typeof(string), typeof(Calculator), new UIPropertyMetadata("0", OnDisplayTextChanged)); |
||||
|
public string DisplayText |
||||
|
{ |
||||
|
get { return (string)GetValue(DisplayTextProperty); } |
||||
|
set { SetValue(DisplayTextProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnDisplayTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Calculator calculator = o as Calculator; |
||||
|
if (calculator != null) |
||||
|
calculator.OnDisplayTextChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnDisplayTextChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //DisplayText
|
||||
|
|
||||
|
#region Memory
|
||||
|
|
||||
|
public static readonly DependencyProperty MemoryProperty = DependencyProperty.Register("Memory", typeof(decimal), typeof(Calculator), new UIPropertyMetadata(default(decimal))); |
||||
|
public decimal Memory |
||||
|
{ |
||||
|
get { return (decimal)GetValue(MemoryProperty); } |
||||
|
set { SetValue(MemoryProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Memory
|
||||
|
|
||||
|
#region Precision
|
||||
|
|
||||
|
public static readonly DependencyProperty PrecisionProperty = DependencyProperty.Register("Precision", typeof(int), typeof(Calculator), new UIPropertyMetadata(6)); |
||||
|
public int Precision |
||||
|
{ |
||||
|
get { return (int)GetValue(PrecisionProperty); } |
||||
|
set { SetValue(PrecisionProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Precision
|
||||
|
|
||||
|
#region Value
|
||||
|
|
||||
|
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(decimal?), typeof(Calculator), new FrameworkPropertyMetadata(default(decimal), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged)); |
||||
|
public decimal? Value |
||||
|
{ |
||||
|
get { return (decimal?)GetValue(ValueProperty); } |
||||
|
set { SetValue(ValueProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Calculator calculator = o as Calculator; |
||||
|
if (calculator != null) |
||||
|
calculator.OnValueChanged((decimal?)e.OldValue, (decimal?)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnValueChanged(decimal? oldValue, decimal? newValue) |
||||
|
{ |
||||
|
if (newValue.HasValue) |
||||
|
DisplayText = newValue.ToString(); |
||||
|
else |
||||
|
DisplayText = "0"; |
||||
|
|
||||
|
RoutedPropertyChangedEventArgs<object> args = new RoutedPropertyChangedEventArgs<object>(oldValue, newValue); |
||||
|
args.RoutedEvent = ValueChangedEvent; |
||||
|
RaiseEvent(args); |
||||
|
} |
||||
|
|
||||
|
#endregion //Value
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static Calculator() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(Calculator), new FrameworkPropertyMetadata(typeof(Calculator))); |
||||
|
} |
||||
|
|
||||
|
public Calculator() |
||||
|
{ |
||||
|
_timer = new DispatcherTimer(); |
||||
|
_timer.Interval = TimeSpan.FromMilliseconds(100); |
||||
|
_timer.Tick += Timer_Tick; |
||||
|
|
||||
|
CommandBindings.Add(new CommandBinding(CalculatorCommands.CalculatorButtonClick, ExecuteCalculatorButtonClick)); |
||||
|
AddHandler(MouseDownEvent, new MouseButtonEventHandler(Calculator_OnMouseDown), true); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_buttonPanel = (ContentControl)GetTemplateChild("PART_CalculatorButtonPanel"); |
||||
|
} |
||||
|
|
||||
|
protected override void OnTextInput(TextCompositionEventArgs e) |
||||
|
{ |
||||
|
var buttonType = CalculatorUtilities.GetCalculatorButtonTypeFromText(e.Text); |
||||
|
if (buttonType != CalculatorButtonType.None) |
||||
|
{ |
||||
|
SimulateCalculatorButtonClick(buttonType); |
||||
|
ProcessCalculatorButton(buttonType); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
private void Calculator_OnMouseDown(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
Focus(); |
||||
|
} |
||||
|
|
||||
|
void Timer_Tick(object sender, EventArgs e) |
||||
|
{ |
||||
|
VisualStateManager.GoToState(_calculatorButton, _calculatorButton.IsMouseOver ? "MouseOver" : "Normal", true); |
||||
|
_timer.Stop(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void Calculate() |
||||
|
{ |
||||
|
if (_lastOperation == Operation.None) |
||||
|
return; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
Value = Decimal.Round(CalculateValue(_lastOperation), Precision); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
Value = null; |
||||
|
DisplayText = "ERROR"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void Calculate(Operation newOperation) |
||||
|
{ |
||||
|
if (!_showNewNumber) |
||||
|
Calculate(); |
||||
|
|
||||
|
_lastOperation = newOperation; |
||||
|
} |
||||
|
|
||||
|
private void Calculate(Operation currentOperation, Operation newOperation) |
||||
|
{ |
||||
|
_lastOperation = currentOperation; |
||||
|
Calculate(); |
||||
|
_lastOperation = newOperation; |
||||
|
} |
||||
|
|
||||
|
private decimal CalculateValue(Operation operation) |
||||
|
{ |
||||
|
decimal newValue = decimal.Zero; |
||||
|
decimal currentValue = CalculatorUtilities.ParseDecimal(DisplayText); |
||||
|
|
||||
|
switch (operation) |
||||
|
{ |
||||
|
case Operation.Add: |
||||
|
newValue = CalculatorUtilities.Add(_previousValue, currentValue); |
||||
|
break; |
||||
|
case Operation.Subtract: |
||||
|
newValue = CalculatorUtilities.Subtract(_previousValue, currentValue); |
||||
|
break; |
||||
|
case Operation.Multiply: |
||||
|
newValue = CalculatorUtilities.Multiply(_previousValue, currentValue); |
||||
|
break; |
||||
|
case Operation.Divide: |
||||
|
newValue = CalculatorUtilities.Divide(_previousValue, currentValue); |
||||
|
break; |
||||
|
//case Operation.Percent:
|
||||
|
// newValue = CalculatorUtilities.Percent(_previousValue, currentValue);
|
||||
|
// break;
|
||||
|
case Operation.Sqrt: |
||||
|
newValue = CalculatorUtilities.SquareRoot(currentValue); |
||||
|
break; |
||||
|
case Operation.Fraction: |
||||
|
newValue = CalculatorUtilities.Fraction(currentValue); |
||||
|
break; |
||||
|
case Operation.Negate: |
||||
|
newValue = CalculatorUtilities.Negate(currentValue); |
||||
|
break; |
||||
|
default: |
||||
|
newValue = decimal.Zero; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return newValue; |
||||
|
} |
||||
|
|
||||
|
void ProcessBackKey() |
||||
|
{ |
||||
|
string displayText; |
||||
|
if (DisplayText.Length > 1 && !(DisplayText.Length == 2 && DisplayText[0] == '-')) |
||||
|
{ |
||||
|
displayText = DisplayText.Remove(DisplayText.Length - 1, 1); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
displayText = "0"; |
||||
|
_showNewNumber = true; |
||||
|
} |
||||
|
|
||||
|
DisplayText = displayText; |
||||
|
} |
||||
|
|
||||
|
private void ProcessCalculatorButton(CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
if (CalculatorUtilities.IsDigit(buttonType)) |
||||
|
ProcessDigitKey(buttonType); |
||||
|
else if ((CalculatorUtilities.IsMemory(buttonType))) |
||||
|
ProcessMemoryKey(buttonType); |
||||
|
else |
||||
|
ProcessOperationKey(buttonType); |
||||
|
|
||||
|
_lastButtonPressed = buttonType; |
||||
|
} |
||||
|
|
||||
|
private void ProcessDigitKey(CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
if (_showNewNumber) |
||||
|
DisplayText = CalculatorUtilities.GetCalculatorButtonContent(buttonType); |
||||
|
else |
||||
|
DisplayText += CalculatorUtilities.GetCalculatorButtonContent(buttonType); |
||||
|
|
||||
|
_showNewNumber = false; |
||||
|
} |
||||
|
|
||||
|
private void ProcessMemoryKey(Calculator.CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
decimal currentValue = CalculatorUtilities.ParseDecimal(DisplayText); |
||||
|
|
||||
|
switch (buttonType) |
||||
|
{ |
||||
|
case Calculator.CalculatorButtonType.MAdd: |
||||
|
Memory += currentValue; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MC: |
||||
|
Memory = decimal.Zero; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MR: |
||||
|
DisplayText = Memory.ToString(); |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MS: |
||||
|
Memory = currentValue; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MSub: |
||||
|
Memory -= currentValue; |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
_showNewNumber = true; |
||||
|
} |
||||
|
|
||||
|
private void ProcessOperationKey(CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
switch (buttonType) |
||||
|
{ |
||||
|
case CalculatorButtonType.Add: |
||||
|
Calculate(Operation.Add); |
||||
|
break; |
||||
|
case CalculatorButtonType.Subtract: |
||||
|
Calculate(Operation.Subtract); |
||||
|
break; |
||||
|
case CalculatorButtonType.Multiply: |
||||
|
Calculate(Operation.Multiply); |
||||
|
break; |
||||
|
case CalculatorButtonType.Divide: |
||||
|
Calculate(Operation.Divide); |
||||
|
break; |
||||
|
case CalculatorButtonType.Percent: |
||||
|
if (_lastOperation != Operation.None) |
||||
|
{ |
||||
|
decimal currentValue = CalculatorUtilities.ParseDecimal(DisplayText); |
||||
|
decimal newValue = CalculatorUtilities.Percent(_previousValue, currentValue); |
||||
|
DisplayText = newValue.ToString(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
DisplayText = "0"; |
||||
|
_showNewNumber = true; |
||||
|
} |
||||
|
return; |
||||
|
case CalculatorButtonType.Sqrt: |
||||
|
Calculate(Operation.Sqrt, Operation.None); |
||||
|
break; |
||||
|
case CalculatorButtonType.Fraction: |
||||
|
Calculate(Operation.Fraction, Operation.None); |
||||
|
break; |
||||
|
case CalculatorButtonType.Negate: |
||||
|
Calculate(Operation.Negate, Operation.None); |
||||
|
break; |
||||
|
case CalculatorButtonType.Equal: |
||||
|
Calculate(Operation.None); |
||||
|
break; |
||||
|
case CalculatorButtonType.Clear: |
||||
|
Calculate(Operation.Clear, Operation.None); |
||||
|
DisplayText = Value.ToString(); |
||||
|
break; |
||||
|
case CalculatorButtonType.Cancel: |
||||
|
DisplayText = _previousValue.ToString(); |
||||
|
_lastOperation = Operation.None; |
||||
|
_showNewNumber = true; |
||||
|
return; |
||||
|
case CalculatorButtonType.Back: |
||||
|
ProcessBackKey(); |
||||
|
return; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
Decimal.TryParse(DisplayText, out _previousValue); |
||||
|
_showNewNumber = true; |
||||
|
} |
||||
|
|
||||
|
private void SimulateCalculatorButtonClick(CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
_calculatorButton = CalculatorUtilities.FindButtonByCalculatorButtonType(_buttonPanel, buttonType); |
||||
|
VisualStateManager.GoToState(_calculatorButton, "Pressed", true); |
||||
|
_timer.Start(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
//Due to a bug in Visual Studio, you cannot create event handlers for nullable args in XAML, so I have to use object instead.
|
||||
|
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<object>), typeof(Calculator)); |
||||
|
public event RoutedPropertyChangedEventHandler<object> ValueChanged |
||||
|
{ |
||||
|
add { AddHandler(ValueChangedEvent, value); } |
||||
|
remove { RemoveHandler(ValueChangedEvent, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
|
||||
|
#region Commands
|
||||
|
|
||||
|
private void ExecuteCalculatorButtonClick(object sender, ExecutedRoutedEventArgs e) |
||||
|
{ |
||||
|
var buttonType = (CalculatorButtonType)e.Parameter; |
||||
|
ProcessCalculatorButton(buttonType); |
||||
|
} |
||||
|
|
||||
|
#endregion //Commands
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Input; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public static class CalculatorCommands |
||||
|
{ |
||||
|
private static RoutedCommand _calculatorButtonClickCommand = new RoutedCommand(); |
||||
|
public static RoutedCommand CalculatorButtonClick |
||||
|
{ |
||||
|
get { return _calculatorButtonClickCommand; } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,496 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters" > |
||||
|
|
||||
|
<coreConverters:CalculatorMemoryToVisibilityConverter x:Key="CalculatorMemoryToVisibilityConverter" /> |
||||
|
|
||||
|
<Style x:Key="CalculatorOperatorButtonStyle" TargetType="{x:Type Button}"> |
||||
|
<Setter Property="Focusable" Value="False"/> |
||||
|
<Setter Property="Foreground" Value="#FF5B636E"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type Button}"> |
||||
|
<Grid x:Name="Control"> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="CommonStates"> |
||||
|
<VisualState x:Name="Normal"/> |
||||
|
<VisualState x:Name="MouseOver"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_MouseOver" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Pressed"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Pressed" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Disabled"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To=".5"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" To=".5"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
<VisualStateGroup x:Name="MemoryStates"> |
||||
|
<VisualState x:Name="EmptyMemory"/> |
||||
|
<VisualState x:Name="MemoryAssigned"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Border1" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Border2" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
<Border Background="White" BorderBrush="{x:Null}" BorderThickness="0" CornerRadius="2" Margin="0,0,0,-1" Opacity="0.5"/> |
||||
|
<Grid x:Name="PART_Default"> |
||||
|
<Border BorderThickness="0" CornerRadius="2" Background="#FF9CA2AB"> |
||||
|
<Grid> |
||||
|
<Border x:Name="PART_Border1" BorderThickness="0" CornerRadius="1" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFEDF1F7" Offset="0"/> |
||||
|
<GradientStop Color="#FFD5DBE3" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="2"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFEDF1F7" Offset="0"/> |
||||
|
<GradientStop Color="#FFD5DBE3" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
<Border x:Name="PART_Border2" BorderThickness="0" CornerRadius="1" Margin="1" Opacity="0"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FF9CA2AB" Offset="0"/> |
||||
|
<GradientStop Color="#FF9CA2AB" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="2"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFEDF1F7" Offset="0"/> |
||||
|
<GradientStop Color="#FFD5DBE3" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<Grid x:Name="PART_MouseOver" Opacity="0"> |
||||
|
<Border BorderThickness="0" CornerRadius="2" Background="#FF9CA2AB"> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFFDFEFF" Offset="0"/> |
||||
|
<GradientStop Color="#FFD9DFE8" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<Grid x:Name="PART_Pressed" Opacity="0"> |
||||
|
<Border BorderThickness="0" CornerRadius="2" Background="#FF90959D"> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1" Background="#FFB5BBC5"/> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<ContentPresenter x:Name="contentPresenter" |
||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
||||
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="CalculatorClearButtonStyle" TargetType="{x:Type Button}"> |
||||
|
<Setter Property="Focusable" Value="False"/> |
||||
|
<Setter Property="Foreground" Value="#FFBF5254"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type Button}"> |
||||
|
<Grid x:Name="Control"> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="CommonStates"> |
||||
|
<VisualState x:Name="Normal"/> |
||||
|
<VisualState x:Name="MouseOver"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_MouseOver" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Pressed"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Pressed" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Disabled"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To=".5"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" To=".5"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
<Border Background="White" BorderBrush="{x:Null}" BorderThickness="0" CornerRadius="2" Margin="0,0,0,-1" Opacity="0.5"/> |
||||
|
<Grid x:Name="PART_Default"> |
||||
|
<Border BorderThickness="0" CornerRadius="2"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFC19497" Offset="0"/> |
||||
|
<GradientStop Color="#FFA67D80" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFFDB8B8" Offset="0"/> |
||||
|
<GradientStop Color="#FFF39998" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<Grid x:Name="PART_MouseOver" Opacity="0"> |
||||
|
<Border BorderThickness="0" CornerRadius="2"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFC19497" Offset="0"/> |
||||
|
<GradientStop Color="#FFA67D80" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFFEC9C9" Offset="0"/> |
||||
|
<GradientStop Color="#FFEAA4A3" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<Grid x:Name="PART_Pressed" Opacity="0"> |
||||
|
<Border BorderThickness="0" CornerRadius="2" Background="#FF9B6F72"> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1" Background="#FFE69197"/> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<ContentPresenter x:Name="contentPresenter" |
||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
||||
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="CalculatorDigitButtonStyle" TargetType="{x:Type Button}"> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Foreground" Value="#FF2A313A"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type Button}"> |
||||
|
<Grid x:Name="Control"> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="CommonStates"> |
||||
|
<VisualState x:Name="Normal"/> |
||||
|
<VisualState x:Name="MouseOver"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_MouseOver" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Pressed"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To="0"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Pressed" Storyboard.TargetProperty="Opacity" To="1"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Disabled"> |
||||
|
<Storyboard> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="PART_Default" Storyboard.TargetProperty="Opacity" To=".5"/> |
||||
|
<DoubleAnimation Duration="0" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" To=".5"/> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
<Border BorderBrush="{x:Null}" BorderThickness="0" Background="White" CornerRadius="3" Margin="0,0,0,-1" Opacity="0.5"/> |
||||
|
<Grid x:Name="PART_Default"> |
||||
|
<Border BorderThickness="0" CornerRadius="2"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFA9AAAB" Offset="0"/> |
||||
|
<GradientStop Color="#FF98999A" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFF6F7F7" Offset="0"/> |
||||
|
<GradientStop Color="#FFDEE0E2" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<Grid x:Name="PART_MouseOver" Opacity="0"> |
||||
|
<Border BorderThickness="0" CornerRadius="2"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFA9AAAB" Offset="0"/> |
||||
|
<GradientStop Color="#FF98999A" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1"> |
||||
|
<Border.Background> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFFCFCFC" Offset="0"/> |
||||
|
<GradientStop Color="#FFEEEFF2" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Border.Background> |
||||
|
</Border> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<Grid x:Name="PART_Pressed" Opacity="0"> |
||||
|
<Border BorderThickness="0" CornerRadius="2" Background="#FF87888A"> |
||||
|
<Border BorderThickness="0" CornerRadius="1" Margin="1" Background="#FFB5BBC5"/> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<ContentPresenter x:Name="contentPresenter" |
||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" |
||||
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
|
||||
|
<ControlTemplate x:Key="CalculatorButtonPanel" TargetType="{x:Type ContentControl}"> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition/> |
||||
|
<ColumnDefinition Width="3"/> |
||||
|
<ColumnDefinition/> |
||||
|
<ColumnDefinition Width="3"/> |
||||
|
<ColumnDefinition/> |
||||
|
<ColumnDefinition Width="3"/> |
||||
|
<ColumnDefinition/> |
||||
|
<ColumnDefinition Width="3"/> |
||||
|
<ColumnDefinition/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="3"/> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="3"/> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="3"/> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="3"/> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="3"/> |
||||
|
<RowDefinition/> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Button Grid.Column="0" Grid.Row="0" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="MC" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="2" Grid.Row="0" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="MR" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="0" Grid.Row="2" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Back" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}" Grid.RowSpan="1"/> |
||||
|
|
||||
|
<Button Grid.Column="2" Grid.Row="2" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Cancel" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorClearButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="4" Grid.Row="2" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Clear" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorClearButtonStyle}" Grid.ColumnSpan="1" Grid.RowSpan="1"/> |
||||
|
|
||||
|
<Button Grid.Column="4" Grid.Row="0" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="MS" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="6" Grid.Row="0" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="MAdd" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}" Margin="0"/> |
||||
|
|
||||
|
<Button Grid.Column="8" Grid.Row="0" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="MSub" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="6" Grid.Row="2" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Negate" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="8" Grid.Row="2" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Sqrt" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="0" Grid.Row="4" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Seven" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="2" Grid.Row="4" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Eight" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="4" Grid.Row="4" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Nine" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="6" Grid.Row="4" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Divide" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="8" Grid.Row="4" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Percent" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="0" Grid.Row="6" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Four" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="2" Grid.Row="6" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Five" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="4" Grid.Row="6" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Six" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="6" Grid.Row="6" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Multiply" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="8" Grid.Row="6" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Fraction" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="0" Grid.Row="8" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="One" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}" /> |
||||
|
|
||||
|
<Button Grid.Column="2" Grid.Row="8" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Two" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="4" Grid.Row="8" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Three" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="6" Grid.Row="8" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Subtract" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="8" Grid.Row="8" Grid.RowSpan="3" MinWidth="28" MinHeight="55" |
||||
|
local:Calculator.CalculatorButtonType="Equal" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
|
||||
|
<Button Grid.Column="0" Grid.Row="10" Grid.ColumnSpan="3" MinWidth="59" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Zero" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}" /> |
||||
|
|
||||
|
<Button Grid.Column="4" Grid.Row="10" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Decimal" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorDigitButtonStyle}" /> |
||||
|
|
||||
|
<Button Grid.Column="6" Grid.Row="10" MinWidth="28" MinHeight="26" |
||||
|
local:Calculator.CalculatorButtonType="Add" |
||||
|
Command="local:CalculatorCommands.CalculatorButtonClick" |
||||
|
Style="{StaticResource CalculatorOperatorButtonStyle}"/> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:Calculator}"> |
||||
|
<Setter Property="Background"> |
||||
|
<Setter.Value> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFFAFBFB" Offset="0"/> |
||||
|
<GradientStop Color="#FFF4F4F4" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
<Setter Property="BorderBrush" Value="#FF949494" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:Calculator}"> |
||||
|
<Border Background="{TemplateBinding Background}" |
||||
|
BorderBrush="{TemplateBinding BorderBrush}" |
||||
|
BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
CornerRadius="3"> |
||||
|
<Grid Margin="10"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="*" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Border x:Name="PART_Display" Margin="0,0,0,10" Background="White" BorderBrush="#FF949494" BorderThickness="1"> |
||||
|
<StackPanel> |
||||
|
<Path Stretch="Fill" Height="9" Width="9" Fill="DarkGray" |
||||
|
Data="F1 M 508.172,390L 506.031,390L 504.612,393.385C 504.174,394.477 503.788,395.533 503.453,396.555L 503.417,396.555C 503.334,395.528 503.206,394.471 503.035,393.385L 502.454,390L 500.301,390L 498.637,399L 500.226,399L 500.807,395.537C 500.903,394.973 501,394.379 501.099,393.756C 501.198,393.133 501.287,392.534 501.367,391.957L 501.402,391.957C 501.444,392.514 501.499,393.08 501.567,393.655C 501.635,394.231 501.712,394.776 501.8,395.292L 502.382,398.871L 503.7,398.871L 505.231,395.233C 505.445,394.724 505.663,394.187 505.884,393.622C 506.105,393.057 506.313,392.502 506.508,391.957L 506.543,391.957C 506.411,393.11 506.304,394.292 506.223,395.502L 505.979,399L 507.637,399L 508.172,390 Z " |
||||
|
HorizontalAlignment="Left" VerticalAlignment="Top" |
||||
|
Margin="4,4,0,0" |
||||
|
Visibility="{Binding Memory, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource CalculatorMemoryToVisibilityConverter}}"/> |
||||
|
<TextBlock FontSize="18" |
||||
|
HorizontalAlignment="Right" |
||||
|
Margin="0,0,4,0" |
||||
|
Text="{Binding DisplayText, RelativeSource={RelativeSource TemplatedParent}}" /> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
<ContentControl x:Name="PART_CalculatorButtonPanel" Grid.Row="1" Template="{StaticResource CalculatorButtonPanel}" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" /> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="IsFocused" Value="True"> |
||||
|
<Setter TargetName="PART_Display" Property="Background" Value="#E7F5FF" /> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,165 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class CalculatorUpDown : DecimalUpDown |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private Popup _calculatorPopup; |
||||
|
private Calculator _calculator; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region DisplayText
|
||||
|
|
||||
|
public static readonly DependencyProperty DisplayTextProperty = DependencyProperty.Register("DisplayText", typeof(string), typeof(CalculatorUpDown), new UIPropertyMetadata("0")); |
||||
|
public string DisplayText |
||||
|
{ |
||||
|
get { return (string)GetValue(DisplayTextProperty); } |
||||
|
set { SetValue(DisplayTextProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //DisplayText
|
||||
|
|
||||
|
#region EnterClosesCalculator
|
||||
|
|
||||
|
public static readonly DependencyProperty EnterClosesCalculatorProperty = DependencyProperty.Register("EnterClosesCalculator", typeof(bool), typeof(CalculatorUpDown), new UIPropertyMetadata(false)); |
||||
|
public bool EnterClosesCalculator |
||||
|
{ |
||||
|
get { return (bool)GetValue(EnterClosesCalculatorProperty); } |
||||
|
set { SetValue(EnterClosesCalculatorProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //EnterClosesCalculator
|
||||
|
|
||||
|
#region IsOpen
|
||||
|
|
||||
|
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(CalculatorUpDown), new UIPropertyMetadata(false, OnIsOpenChanged)); |
||||
|
public bool IsOpen |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsOpenProperty); } |
||||
|
set { SetValue(IsOpenProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnIsOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
CalculatorUpDown calculatorUpDown = o as CalculatorUpDown; |
||||
|
if (calculatorUpDown != null) |
||||
|
calculatorUpDown.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endregion //IsOpen
|
||||
|
|
||||
|
#region Memory
|
||||
|
|
||||
|
public static readonly DependencyProperty MemoryProperty = DependencyProperty.Register("Memory", typeof(decimal), typeof(CalculatorUpDown), new UIPropertyMetadata(default(decimal))); |
||||
|
public decimal Memory |
||||
|
{ |
||||
|
get { return (decimal)GetValue(MemoryProperty); } |
||||
|
set { SetValue(MemoryProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Memory
|
||||
|
|
||||
|
#region Precision
|
||||
|
|
||||
|
public static readonly DependencyProperty PrecisionProperty = DependencyProperty.Register("Precision", typeof(int), typeof(CalculatorUpDown), new UIPropertyMetadata(6)); |
||||
|
public int Precision |
||||
|
{ |
||||
|
get { return (int)GetValue(PrecisionProperty); } |
||||
|
set { SetValue(PrecisionProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Precision
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static CalculatorUpDown() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(CalculatorUpDown), new FrameworkPropertyMetadata(typeof(CalculatorUpDown))); |
||||
|
} |
||||
|
|
||||
|
public CalculatorUpDown() |
||||
|
{ |
||||
|
Keyboard.AddKeyDownHandler(this, OnKeyDown); |
||||
|
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
_calculatorPopup = (Popup)GetTemplateChild("PART_CalculatorPopup"); |
||||
|
_calculatorPopup.Opened += CalculatorPopup_Opened; |
||||
|
|
||||
|
_calculator = (Calculator)GetTemplateChild("PART_Calculator"); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void CalculatorPopup_Opened(object sender, EventArgs e) |
||||
|
{ |
||||
|
_calculator.Focus(); |
||||
|
} |
||||
|
|
||||
|
private void OnKeyDown(object sender, KeyEventArgs e) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Enter: |
||||
|
{ |
||||
|
if (EnterClosesCalculator && IsOpen) |
||||
|
CloseCalculatorUpDown(); |
||||
|
break; |
||||
|
} |
||||
|
case Key.Escape: |
||||
|
{ |
||||
|
CloseCalculatorUpDown(); |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
} |
||||
|
case Key.Tab: |
||||
|
{ |
||||
|
CloseCalculatorUpDown(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
CloseCalculatorUpDown(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void CloseCalculatorUpDown() |
||||
|
{ |
||||
|
if (IsOpen) |
||||
|
IsOpen = false; |
||||
|
ReleaseMouseCapture(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,120 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"> |
||||
|
|
||||
|
<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 x:Key="CalculatorToggleButtonStyle" TargetType="ToggleButton"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="ToggleButton"> |
||||
|
<Grid SnapsToDevicePixels="True"> |
||||
|
<chrome:ButtonChrome x:Name="ToggleButtonChrome" |
||||
|
CornerRadius="0,2.75,2.75,0" |
||||
|
RenderMouseOver="{TemplateBinding IsMouseOver}" |
||||
|
RenderPressed="{TemplateBinding IsPressed}" /> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> |
||||
|
|
||||
|
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Grid.Column="1" Margin="5"> |
||||
|
<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> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<DataTemplate x:Key="DefaultWatermarkTemplate"> |
||||
|
<ContentControl Content="{Binding}" Foreground="Gray" Focusable="False" /> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- CalculatorUpDown --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:CalculatorUpDown}"> |
||||
|
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> |
||||
|
<Setter Property="BorderThickness" Value="1,1,0,1" /> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Right" /> |
||||
|
<Setter Property="TextAlignment" Value="Right" /> |
||||
|
<Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:CalculatorUpDown}"> |
||||
|
<Grid> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*" /> |
||||
|
<ColumnDefinition Width="Auto" /> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<local:ButtonSpinner x:Name="Spinner" IsTabStop="False" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
AllowSpin="{TemplateBinding AllowSpin}" ShowButtonSpinner="{TemplateBinding ShowButtonSpinner}"> |
||||
|
<local:WatermarkTextBox x:Name="TextBox" BorderThickness="0" |
||||
|
Background="{TemplateBinding Background}" |
||||
|
FontFamily="{TemplateBinding FontFamily}" |
||||
|
FontSize="{TemplateBinding FontSize}" |
||||
|
FontStretch="{TemplateBinding FontStretch}" |
||||
|
FontStyle="{TemplateBinding FontStyle}" |
||||
|
FontWeight="{TemplateBinding FontWeight}" |
||||
|
Foreground="{TemplateBinding Foreground}" |
||||
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
IsReadOnly="{Binding IsEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" |
||||
|
MinWidth="20" AcceptsReturn="False" |
||||
|
TextAlignment="{TemplateBinding TextAlignment}" |
||||
|
TextWrapping="NoWrap" |
||||
|
TabIndex="{TemplateBinding TabIndex}" |
||||
|
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Watermark="{TemplateBinding Watermark}" |
||||
|
WatermarkTemplate="{TemplateBinding WatermarkTemplate}"/> |
||||
|
</local:ButtonSpinner> |
||||
|
<ToggleButton x:Name="_calculatorToggleButton" Grid.Column="1" |
||||
|
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Style="{StaticResource CalculatorToggleButtonStyle}" |
||||
|
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> |
||||
|
</Grid> |
||||
|
<Popup x:Name="PART_CalculatorPopup" IsOpen="{Binding IsChecked, ElementName=_calculatorToggleButton}" StaysOpen="False"> |
||||
|
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource PopupDarkBorderBrush}" Padding="3"> |
||||
|
<StackPanel> |
||||
|
<local:Calculator x:Name="PART_Calculator" Background="Transparent" BorderThickness="0" |
||||
|
DisplayText="{Binding DisplayText, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Memory="{Binding Memory, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Precision="{Binding Precision, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Value="{Binding Value, RelativeSource={RelativeSource TemplatedParent}}" /> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
</Popup> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,150 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows.Input; |
||||
|
using System.ComponentModel; |
||||
|
using System.Collections; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class CheckListBox : ItemsControl |
||||
|
{ |
||||
|
private bool _surpressSelectionChanged; |
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static CheckListBox() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckListBox), new FrameworkPropertyMetadata(typeof(CheckListBox))); |
||||
|
} |
||||
|
|
||||
|
public CheckListBox() |
||||
|
{ |
||||
|
SelectedItems = new List<object>(); |
||||
|
AddHandler(CheckListBox.SelectedEvent, new RoutedEventHandler(CheckListBox_Selected)); |
||||
|
AddHandler(CheckListBox.UnselectedEvent, new RoutedEventHandler(CheckListBox_Unselected)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
public static readonly DependencyProperty CheckedMemberPathProperty = DependencyProperty.Register("CheckedMemberPath", typeof(string), typeof(CheckListBox), new UIPropertyMetadata(null)); |
||||
|
public string CheckedMemberPath |
||||
|
{ |
||||
|
get { return (string)GetValue(CheckedMemberPathProperty); } |
||||
|
set { SetValue(CheckedMemberPathProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CheckListBox), new PropertyMetadata((ICommand)null)); |
||||
|
[TypeConverter(typeof(CommandConverter))] |
||||
|
public ICommand Command |
||||
|
{ |
||||
|
get { return (ICommand)GetValue(CommandProperty); } |
||||
|
set { SetValue(CommandProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#region SelectedItem
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(CheckListBox), new UIPropertyMetadata(null, OnSelectedItemChanged)); |
||||
|
public object SelectedItem |
||||
|
{ |
||||
|
get { return (object)GetValue(SelectedItemProperty); } |
||||
|
set { SetValue(SelectedItemProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnSelectedItemChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
CheckListBox checkListBox = o as CheckListBox; |
||||
|
if (checkListBox != null) |
||||
|
checkListBox.OnSelectedItemChanged((object)e.OldValue, (object)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnSelectedItemChanged(object oldValue, object newValue) |
||||
|
{ |
||||
|
OnSelectionChanged(); |
||||
|
} |
||||
|
|
||||
|
#endregion //SelectedItem
|
||||
|
|
||||
|
public IList SelectedItems { get; private set; } |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
protected override DependencyObject GetContainerForItemOverride() |
||||
|
{ |
||||
|
return new CheckListBoxItem(); |
||||
|
} |
||||
|
|
||||
|
protected override bool IsItemItsOwnContainerOverride(object item) |
||||
|
{ |
||||
|
return item is CheckListBoxItem; |
||||
|
} |
||||
|
|
||||
|
protected override void PrepareContainerForItemOverride(DependencyObject element, object item) |
||||
|
{ |
||||
|
_surpressSelectionChanged = true; |
||||
|
var checkListBoxItem = element as FrameworkElement; |
||||
|
if (!String.IsNullOrEmpty(CheckedMemberPath)) |
||||
|
{ |
||||
|
Binding isCheckedBinding = new Binding(CheckedMemberPath); |
||||
|
isCheckedBinding.Source = item; |
||||
|
checkListBoxItem.SetBinding(CheckListBoxItem.IsSelectedProperty, isCheckedBinding); |
||||
|
} |
||||
|
base.PrepareContainerForItemOverride(element, item); |
||||
|
_surpressSelectionChanged = false; |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble, typeof(SelectionChangedEventHandler), typeof(CheckListBox)); |
||||
|
public static readonly RoutedEvent UnselectedEvent = EventManager.RegisterRoutedEvent("Unselected", RoutingStrategy.Bubble, typeof(SelectionChangedEventHandler), typeof(CheckListBox)); |
||||
|
public static readonly RoutedEvent SelectionChangedEvent = EventManager.RegisterRoutedEvent("SelectionChanged", RoutingStrategy.Bubble, typeof(CheckListBoxSelectionChangedEventHandler), typeof(CheckListBox)); |
||||
|
public event CheckListBoxSelectionChangedEventHandler SelectionChanged |
||||
|
{ |
||||
|
add { AddHandler(SelectionChangedEvent, value); } |
||||
|
remove { RemoveHandler(SelectionChangedEvent, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
|
||||
|
void CheckListBox_Selected(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
SetSelectedItem(e.OriginalSource); |
||||
|
SelectedItems.Add(SelectedItem); |
||||
|
} |
||||
|
|
||||
|
void CheckListBox_Unselected(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
SetSelectedItem(e.OriginalSource); |
||||
|
SelectedItems.Remove(SelectedItem); |
||||
|
} |
||||
|
|
||||
|
private void SetSelectedItem(object source) |
||||
|
{ |
||||
|
if (_surpressSelectionChanged) |
||||
|
return; |
||||
|
|
||||
|
var selectedCheckListBoxItem = source as FrameworkElement; |
||||
|
if (selectedCheckListBoxItem != null) |
||||
|
SelectedItem = selectedCheckListBoxItem.DataContext; |
||||
|
} |
||||
|
|
||||
|
private void OnSelectionChanged() |
||||
|
{ |
||||
|
if (_surpressSelectionChanged) |
||||
|
return; |
||||
|
|
||||
|
RaiseEvent(new CheckListBoxSelectionChangedEventArgs(CheckListBox.SelectionChangedEvent, this, SelectedItem)); |
||||
|
|
||||
|
if (Command != null) |
||||
|
Command.Execute(SelectedItem); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,81 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Media.Imaging; |
||||
|
using System.Windows.Navigation; |
||||
|
using System.Windows.Shapes; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class CheckListBoxItem : ContentControl |
||||
|
{ |
||||
|
static CheckListBoxItem() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckListBoxItem), new FrameworkPropertyMetadata(typeof(CheckListBoxItem))); |
||||
|
} |
||||
|
|
||||
|
public CheckListBoxItem() |
||||
|
{ |
||||
|
AddHandler(Mouse.MouseDownEvent, new MouseButtonEventHandler(CheckListBoxItem_MouseDown)); |
||||
|
} |
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(CheckListBoxItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsSelectedChanged)); |
||||
|
public bool IsSelected |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsSelectedProperty); } |
||||
|
set { SetValue(IsSelectedProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnIsSelectedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
CheckListBoxItem checkListBoxItem = o as CheckListBoxItem; |
||||
|
if (checkListBoxItem != null) |
||||
|
checkListBoxItem.OnIsSelectedChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
if (newValue) |
||||
|
RaiseSelectionChangedEvent(new RoutedEventArgs(CheckListBox.SelectedEvent, this)); |
||||
|
else |
||||
|
RaiseSelectionChangedEvent(new RoutedEventArgs(CheckListBox.UnselectedEvent, this)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
public static readonly RoutedEvent SelectedEvent = CheckListBox.SelectedEvent.AddOwner(typeof(CheckListBoxItem)); |
||||
|
public static readonly RoutedEvent UnselectedEvent = CheckListBox.UnselectedEvent.AddOwner(typeof(CheckListBoxItem)); |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Event Hanlders
|
||||
|
|
||||
|
void CheckListBoxItem_MouseDown(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
IsSelected = !IsSelected; |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Hanlders
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void RaiseSelectionChangedEvent(RoutedEventArgs e) |
||||
|
{ |
||||
|
base.RaiseEvent(e); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public delegate void CheckListBoxSelectionChangedEventHandler(object sender, CheckListBoxSelectionChangedEventArgs e); |
||||
|
public class CheckListBoxSelectionChangedEventArgs : RoutedEventArgs |
||||
|
{ |
||||
|
public object Item { get; private set; } |
||||
|
|
||||
|
public CheckListBoxSelectionChangedEventArgs(RoutedEvent routedEvent, object source, object item) |
||||
|
: base(routedEvent, source) |
||||
|
{ |
||||
|
Item = item; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:CheckListBox}"> |
||||
|
<Setter Property="BorderBrush" Value="#FF707070" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="KeyboardNavigation.TabNavigation" Value="Once"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:CheckListBox}"> |
||||
|
<Border Background="{TemplateBinding Background}" |
||||
|
BorderBrush="{TemplateBinding BorderBrush}" |
||||
|
BorderThickness="{TemplateBinding BorderThickness}"> |
||||
|
<ScrollViewer Padding="{TemplateBinding Padding}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"> |
||||
|
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> |
||||
|
</ScrollViewer> |
||||
|
</Border> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:CheckListBoxItem}" > |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:CheckListBoxItem}"> |
||||
|
<Border x:Name="_background" |
||||
|
Background="{TemplateBinding Background}" |
||||
|
BorderBrush="{TemplateBinding BorderBrush}" |
||||
|
BorderThickness="{TemplateBinding BorderThickness}"> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
<ColumnDefinition Width="*" /> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<CheckBox Name="PART_CheckBox" IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
VerticalAlignment="Center" Focusable="False" Margin="3,1,5,1"/> |
||||
|
<Border Grid.Column="1"> |
||||
|
<ContentPresenter Margin="2" ContentSource="Content" /> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
|
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="IsMouseOver" Value="true"> |
||||
|
<Setter TargetName="_background" Property="Background" Value="Blue"/> |
||||
|
<Setter Property="Foreground" Value="White"/> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,743 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
using System.ComponentModel; |
||||
|
using System.Windows.Shapes; |
||||
|
using System.Windows.Threading; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class ChildWindow : ContentControl |
||||
|
{ |
||||
|
#region Private Members
|
||||
|
|
||||
|
private Grid _root; |
||||
|
private TranslateTransform _moveTransform = new TranslateTransform(); |
||||
|
private bool _startupPositionInitialized; |
||||
|
private bool _isMouseCaptured; |
||||
|
private Point _clickPoint; |
||||
|
private Point _oldPosition; |
||||
|
private Border _dragWidget; |
||||
|
private FrameworkElement _parentContainer; |
||||
|
private Rectangle _modalLayer = new Rectangle(); |
||||
|
private Canvas _modalLayerPanel = new Canvas(); |
||||
|
|
||||
|
private const int _horizaontalOffset = 3; |
||||
|
private const int _verticalOffset = 3; |
||||
|
|
||||
|
bool _ignorePropertyChanged; |
||||
|
|
||||
|
#endregion //Private Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region Internal Properties
|
||||
|
|
||||
|
internal Grid WindowRoot { get; private set; } |
||||
|
internal Thumb DragWidget { get; private set; } |
||||
|
internal Button MinimizeButton { get; private set; } |
||||
|
internal Button MaximizeButton { get; private set; } |
||||
|
internal Button CloseButton { get; private set; } |
||||
|
|
||||
|
#endregion //Internal Properties
|
||||
|
|
||||
|
#region Public Properties
|
||||
|
|
||||
|
#region Caption
|
||||
|
|
||||
|
public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register("Caption", typeof(object), typeof(ChildWindow), new UIPropertyMetadata(String.Empty)); |
||||
|
public object Caption |
||||
|
{ |
||||
|
get { return (object)GetValue(CaptionProperty); } |
||||
|
set { SetValue(CaptionProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Caption
|
||||
|
|
||||
|
#region CaptionForeground
|
||||
|
|
||||
|
public static readonly DependencyProperty CaptionForegroundProperty = DependencyProperty.Register("CaptionForeground", typeof(Brush), typeof(ChildWindow), new UIPropertyMetadata(null)); |
||||
|
public Brush CaptionForeground |
||||
|
{ |
||||
|
get { return (Brush)GetValue(CaptionForegroundProperty); } |
||||
|
set { SetValue(CaptionForegroundProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //CaptionForeground
|
||||
|
|
||||
|
#region CloseButtonStyle
|
||||
|
|
||||
|
public static readonly DependencyProperty CloseButtonStyleProperty = DependencyProperty.Register("CloseButtonStyle", typeof(Style), typeof(ChildWindow), new PropertyMetadata(null)); |
||||
|
public Style CloseButtonStyle |
||||
|
{ |
||||
|
get { return (Style)GetValue(CloseButtonStyleProperty); } |
||||
|
set { SetValue(CloseButtonStyleProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //CloseButtonStyle
|
||||
|
|
||||
|
#region CloseButtonVisibility
|
||||
|
|
||||
|
public static readonly DependencyProperty CloseButtonVisibilityProperty = DependencyProperty.Register("CloseButtonVisibility", typeof(Visibility), typeof(ChildWindow), new PropertyMetadata(Visibility.Visible)); |
||||
|
public Visibility CloseButtonVisibility |
||||
|
{ |
||||
|
get { return (Visibility)GetValue(CloseButtonVisibilityProperty); } |
||||
|
set { SetValue(CloseButtonVisibilityProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //CloseButtonVisibility
|
||||
|
|
||||
|
#region DialogResult
|
||||
|
|
||||
|
private bool? _dialogResult; |
||||
|
/// <summary>
|
||||
|
/// Gets or sets a value indicating whether the ChildWindow was accepted or canceled.
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// True if the child window was accepted; false if the child window was
|
||||
|
/// canceled. The default is null.
|
||||
|
/// </value>
|
||||
|
[TypeConverter(typeof(NullableBoolConverter))] |
||||
|
public bool? DialogResult |
||||
|
{ |
||||
|
get { return _dialogResult; } |
||||
|
set |
||||
|
{ |
||||
|
if (_dialogResult != value) |
||||
|
{ |
||||
|
_dialogResult = value; |
||||
|
Close(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //DialogResult
|
||||
|
|
||||
|
#region DesignerWindowState
|
||||
|
|
||||
|
public static readonly DependencyProperty DesignerWindowStateProperty = DependencyProperty.Register("DesignerWindowState", typeof(WindowState), typeof(ChildWindow), new PropertyMetadata(WindowState.Closed, OnDesignerWindowStatePropertyChanged)); |
||||
|
public WindowState DesignerWindowState |
||||
|
{ |
||||
|
get { return (WindowState)GetValue(DesignerWindowStateProperty); } |
||||
|
set { SetValue(DesignerWindowStateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnDesignerWindowStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = d as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnDesignerWindowStatePropertyChanged((WindowState)e.OldValue, (WindowState)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnDesignerWindowStatePropertyChanged(WindowState oldValue, WindowState newValue) |
||||
|
{ |
||||
|
if (DesignerProperties.GetIsInDesignMode(this)) |
||||
|
{ |
||||
|
Visibility = newValue == Controls.WindowState.Open ? Visibility.Visible : Visibility.Collapsed; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //DesignerWindowState
|
||||
|
|
||||
|
#region FocusedElement
|
||||
|
|
||||
|
public static readonly DependencyProperty FocusedElementProperty = DependencyProperty.Register("FocusedElement", typeof(FrameworkElement), typeof(ChildWindow), new UIPropertyMetadata(null)); |
||||
|
public FrameworkElement FocusedElement |
||||
|
{ |
||||
|
get { return (FrameworkElement)GetValue(FocusedElementProperty); } |
||||
|
set { SetValue(FocusedElementProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region IsModal
|
||||
|
|
||||
|
public static readonly DependencyProperty IsModalProperty = DependencyProperty.Register("IsModal", typeof(bool), typeof(ChildWindow), new UIPropertyMetadata(false, new PropertyChangedCallback(OnIsModalPropertyChanged))); |
||||
|
public bool IsModal |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsModalProperty); } |
||||
|
set { SetValue(IsModalProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnIsModalPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = d as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnIsModalChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
private void OnIsModalChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
if (newValue) |
||||
|
{ |
||||
|
KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Cycle); |
||||
|
ShowModalLayer(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Continue); |
||||
|
HideModalLayer(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //IsModal
|
||||
|
|
||||
|
#region Left
|
||||
|
|
||||
|
public static readonly DependencyProperty LeftProperty = DependencyProperty.Register("Left", typeof(double), typeof(ChildWindow), new PropertyMetadata(0.0, new PropertyChangedCallback(OnLeftPropertyChanged))); |
||||
|
public double Left |
||||
|
{ |
||||
|
get { return (double)GetValue(LeftProperty); } |
||||
|
set { SetValue(LeftProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnLeftPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = obj as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnLeftPropertyChanged((double)e.OldValue, (double)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
private void OnLeftPropertyChanged(double oldValue, double newValue) |
||||
|
{ |
||||
|
Left = GetRestrictedLeft(); |
||||
|
ProcessMove(newValue - oldValue, 0); |
||||
|
} |
||||
|
|
||||
|
#endregion //Left
|
||||
|
|
||||
|
#region OverlayBrush
|
||||
|
|
||||
|
public static readonly DependencyProperty OverlayBrushProperty = DependencyProperty.Register("OverlayBrush", typeof(Brush), typeof(ChildWindow), new PropertyMetadata(Brushes.Gray, OnOverlayBrushChanged)); |
||||
|
public Brush OverlayBrush |
||||
|
{ |
||||
|
get { return (Brush)GetValue(OverlayBrushProperty); } |
||||
|
set { SetValue(OverlayBrushProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnOverlayBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = d as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnOverlayBrushChanged((Brush)e.OldValue, (Brush)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnOverlayBrushChanged(Brush oldValue, Brush newValue) |
||||
|
{ |
||||
|
_modalLayer.Fill = newValue; |
||||
|
} |
||||
|
|
||||
|
#endregion //OverlayBrush
|
||||
|
|
||||
|
#region OverlayOpacity
|
||||
|
|
||||
|
public static readonly DependencyProperty OverlayOpacityProperty = DependencyProperty.Register("OverlayOpacity", typeof(double), typeof(ChildWindow), new PropertyMetadata(0.5, OnOverlayOpacityChanged)); |
||||
|
public double OverlayOpacity |
||||
|
{ |
||||
|
get { return (double)GetValue(OverlayOpacityProperty); } |
||||
|
set { SetValue(OverlayOpacityProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnOverlayOpacityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = d as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnOverlayOpacityChanged((double)e.OldValue, (double)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnOverlayOpacityChanged(double oldValue, double newValue) |
||||
|
{ |
||||
|
_modalLayer.Opacity = newValue; |
||||
|
} |
||||
|
|
||||
|
#endregion //OverlayOpacity
|
||||
|
|
||||
|
#region Top
|
||||
|
|
||||
|
public static readonly DependencyProperty TopProperty = DependencyProperty.Register("Top", typeof(double), typeof(ChildWindow), new PropertyMetadata(0.0, new PropertyChangedCallback(OnTopPropertyChanged))); |
||||
|
public double Top |
||||
|
{ |
||||
|
get { return (double)GetValue(TopProperty); } |
||||
|
set { SetValue(TopProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnTopPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = obj as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnTopPropertyChanged((double)e.OldValue, (double)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
private void OnTopPropertyChanged(double oldValue, double newValue) |
||||
|
{ |
||||
|
Top = GetRestrictedTop(); |
||||
|
ProcessMove(0, newValue - oldValue); |
||||
|
} |
||||
|
|
||||
|
#endregion //TopProperty
|
||||
|
|
||||
|
#region WindowBackground
|
||||
|
|
||||
|
public static readonly DependencyProperty WindowBackgroundProperty = DependencyProperty.Register("WindowBackground", typeof(Brush), typeof(ChildWindow), new PropertyMetadata(null)); |
||||
|
public Brush WindowBackground |
||||
|
{ |
||||
|
get { return (Brush)GetValue(WindowBackgroundProperty); } |
||||
|
set { SetValue(WindowBackgroundProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //WindowBackground
|
||||
|
|
||||
|
#region WindowBorderBrush
|
||||
|
|
||||
|
public static readonly DependencyProperty WindowBorderBrushProperty = DependencyProperty.Register("WindowBorderBrush", typeof(Brush), typeof(ChildWindow), new PropertyMetadata(null)); |
||||
|
public Brush WindowBorderBrush |
||||
|
{ |
||||
|
get { return (Brush)GetValue(WindowBorderBrushProperty); } |
||||
|
set { SetValue(WindowBorderBrushProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //WindowBorderBrush
|
||||
|
|
||||
|
#region WindowOpacity
|
||||
|
|
||||
|
public static readonly DependencyProperty WindowOpacityProperty = DependencyProperty.Register("WindowOpacity", typeof(double), typeof(ChildWindow), new PropertyMetadata(null)); |
||||
|
public double WindowOpacity |
||||
|
{ |
||||
|
get { return (double)GetValue(WindowOpacityProperty); } |
||||
|
set { SetValue(WindowOpacityProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //WindowOpacity
|
||||
|
|
||||
|
#region WindowStartupLocation
|
||||
|
|
||||
|
public static readonly DependencyProperty WindowStartupLocationProperty = DependencyProperty.Register("WindowStartupLocation", typeof(WindowStartupLocation), typeof(ChildWindow), new UIPropertyMetadata(WindowStartupLocation.Manual, OnWindowStartupLocationChanged)); |
||||
|
public WindowStartupLocation WindowStartupLocation |
||||
|
{ |
||||
|
get { return (WindowStartupLocation)GetValue(WindowStartupLocationProperty); } |
||||
|
set { SetValue(WindowStartupLocationProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnWindowStartupLocationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = o as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnWindowStartupLocationChanged((WindowStartupLocation)e.OldValue, (WindowStartupLocation)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnWindowStartupLocationChanged(WindowStartupLocation oldValue, WindowStartupLocation newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //WindowStartupLocation
|
||||
|
|
||||
|
#region WindowState
|
||||
|
|
||||
|
public static readonly DependencyProperty WindowStateProperty = DependencyProperty.Register("WindowState", typeof(WindowState), typeof(ChildWindow), new FrameworkPropertyMetadata(WindowState.Closed, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnWindowStatePropertyChanged)); |
||||
|
public WindowState WindowState |
||||
|
{ |
||||
|
get { return (WindowState)GetValue(WindowStateProperty); } |
||||
|
set { SetValue(WindowStateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnWindowStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ChildWindow childWindow = d as ChildWindow; |
||||
|
if (childWindow != null) |
||||
|
childWindow.OnWindowStatePropertyChanged((WindowState)e.OldValue, (WindowState)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnWindowStatePropertyChanged(WindowState oldValue, WindowState newValue) |
||||
|
{ |
||||
|
if (!DesignerProperties.GetIsInDesignMode(this)) |
||||
|
{ |
||||
|
if (!_ignorePropertyChanged) |
||||
|
SetWindowState(newValue); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Visibility = DesignerWindowState == Controls.WindowState.Open ? Visibility.Visible : System.Windows.Visibility.Collapsed; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //WindowState
|
||||
|
|
||||
|
#endregion //Public Properties
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static ChildWindow() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ChildWindow), new FrameworkPropertyMetadata(typeof(ChildWindow))); |
||||
|
} |
||||
|
|
||||
|
public ChildWindow() |
||||
|
{ |
||||
|
DesignerWindowState = Controls.WindowState.Open; |
||||
|
|
||||
|
IsVisibleChanged += ChildWindow_IsVisibleChanged; |
||||
|
|
||||
|
_modalLayer.Fill = OverlayBrush; |
||||
|
_modalLayer.Opacity = OverlayOpacity; |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_dragWidget = (Border)GetTemplateChild("PART_DragWidget"); |
||||
|
if (_dragWidget != null) |
||||
|
{ |
||||
|
_dragWidget.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(HeaderLeftMouseButtonDown), true); |
||||
|
_dragWidget.AddHandler(UIElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderMouseLeftButtonUp), true); |
||||
|
_dragWidget.MouseMove += (o, e) => HeaderMouseMove(e); |
||||
|
} |
||||
|
|
||||
|
CloseButton = (Button)GetTemplateChild("PART_CloseButton"); |
||||
|
if (CloseButton != null) |
||||
|
CloseButton.Click += (o, e) => Close(); |
||||
|
|
||||
|
WindowRoot = GetTemplateChild("PART_WindowRoot") as Grid; |
||||
|
WindowRoot.RenderTransform = _moveTransform; |
||||
|
|
||||
|
_parentContainer = VisualTreeHelper.GetParent(this) as FrameworkElement; |
||||
|
_parentContainer.LayoutUpdated += ParentContainer_LayoutUpdated; |
||||
|
_parentContainer.SizeChanged += ParentContainer_SizeChanged; |
||||
|
|
||||
|
//initialize our modal background width/height
|
||||
|
_modalLayer.Height = _parentContainer.ActualHeight; |
||||
|
_modalLayer.Width = _parentContainer.ActualWidth; |
||||
|
|
||||
|
//this is for XBAP applications only. When inside an XBAP the parent container has no height or width until it has loaded. Therefore
|
||||
|
//we need to handle the loaded event and reposition the window.
|
||||
|
if (System.Windows.Interop.BrowserInteropHelper.IsBrowserHosted) |
||||
|
{ |
||||
|
_parentContainer.Loaded += (o, e) => |
||||
|
{ |
||||
|
ExecuteOpen(); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
_root = GetTemplateChild("Root") as Grid; |
||||
|
|
||||
|
#if VS2008
|
||||
|
FocusVisualStyle = null; |
||||
|
#else
|
||||
|
Style focusStyle = _root.Resources["FocusVisualStyle"] as Style; |
||||
|
if (focusStyle != null) |
||||
|
{ |
||||
|
Setter focusStyleDataContext = new Setter(Control.DataContextProperty, this); |
||||
|
focusStyle.Setters.Add(focusStyleDataContext); |
||||
|
FocusVisualStyle = focusStyle; |
||||
|
} |
||||
|
#endif
|
||||
|
_root.Children.Add(_modalLayerPanel); |
||||
|
} |
||||
|
|
||||
|
protected override void OnGotFocus(RoutedEventArgs e) |
||||
|
{ |
||||
|
Action action = () => |
||||
|
{ |
||||
|
if (FocusedElement != null) |
||||
|
FocusedElement.Focus(); |
||||
|
}; |
||||
|
|
||||
|
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, action); |
||||
|
} |
||||
|
|
||||
|
protected override void OnKeyDown(KeyEventArgs e) |
||||
|
{ |
||||
|
base.OnKeyDown(e); |
||||
|
|
||||
|
if (WindowState == WindowState.Open) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Left: |
||||
|
this.Left -= _horizaontalOffset; |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
|
||||
|
case Key.Right: |
||||
|
this.Left += _horizaontalOffset; |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
|
||||
|
case Key.Down: |
||||
|
this.Top += _verticalOffset; |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
|
||||
|
case Key.Up: |
||||
|
this.Top -= _verticalOffset; |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void ChildWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
if ((bool)e.NewValue) |
||||
|
Focus(); |
||||
|
} |
||||
|
|
||||
|
void HeaderLeftMouseButtonDown(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
Focus(); |
||||
|
_dragWidget.CaptureMouse(); |
||||
|
_isMouseCaptured = true; |
||||
|
_clickPoint = e.GetPosition(null); //save off the mouse position
|
||||
|
_oldPosition = new Point(Left, Top); //save off our original window position
|
||||
|
} |
||||
|
|
||||
|
private void HeaderMouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
_dragWidget.ReleaseMouseCapture(); |
||||
|
_isMouseCaptured = false; |
||||
|
} |
||||
|
|
||||
|
private void HeaderMouseMove(MouseEventArgs e) |
||||
|
{ |
||||
|
if (_isMouseCaptured && Visibility == Visibility.Visible) |
||||
|
{ |
||||
|
Point currentPosition = e.GetPosition(null); //our current mouse position
|
||||
|
|
||||
|
Left = _oldPosition.X + (currentPosition.X - _clickPoint.X); |
||||
|
Top = _oldPosition.Y + (currentPosition.Y - _clickPoint.Y); |
||||
|
|
||||
|
//this helps keep our mouse position in sync with the drag widget position
|
||||
|
Point dragWidgetPosition = e.GetPosition(_dragWidget); |
||||
|
if (dragWidgetPosition.X < 0 || dragWidgetPosition.X > _dragWidget.ActualWidth || dragWidgetPosition.Y < 0 || dragWidgetPosition.Y > _dragWidget.ActualHeight) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_oldPosition = new Point(Left, Top); |
||||
|
_clickPoint = e.GetPosition(Window.GetWindow(this)); //store the point where we are relative to the window
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ParentContainer_LayoutUpdated(object sender, EventArgs e) |
||||
|
{ |
||||
|
if (DesignerProperties.GetIsInDesignMode(this)) |
||||
|
return; |
||||
|
|
||||
|
//we only want to set the start position if this is the first time the control has bee initialized
|
||||
|
if (!_startupPositionInitialized) |
||||
|
{ |
||||
|
ExecuteOpen(); |
||||
|
_startupPositionInitialized = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ParentContainer_SizeChanged(object sender, SizeChangedEventArgs e) |
||||
|
{ |
||||
|
//resize our modal layer
|
||||
|
_modalLayer.Height = e.NewSize.Height; |
||||
|
_modalLayer.Width = e.NewSize.Width; |
||||
|
|
||||
|
//reposition our window
|
||||
|
Left = GetRestrictedLeft(); |
||||
|
Top = GetRestrictedTop(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
#region Private
|
||||
|
|
||||
|
private double GetRestrictedLeft() |
||||
|
{ |
||||
|
if (Left < 0) |
||||
|
return 0; |
||||
|
|
||||
|
if (_parentContainer != null) |
||||
|
{ |
||||
|
if (Left + WindowRoot.ActualWidth > _parentContainer.ActualWidth && _parentContainer.ActualWidth != 0) |
||||
|
{ |
||||
|
double left = _parentContainer.ActualWidth - WindowRoot.ActualWidth; |
||||
|
return left < 0 ? 0 : left; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return Left; |
||||
|
} |
||||
|
|
||||
|
private double GetRestrictedTop() |
||||
|
{ |
||||
|
if (Top < 0) |
||||
|
return 0; |
||||
|
|
||||
|
if (_parentContainer != null) |
||||
|
{ |
||||
|
if (Top + WindowRoot.ActualHeight > _parentContainer.ActualHeight && _parentContainer.ActualHeight != 0) |
||||
|
{ |
||||
|
double top = _parentContainer.ActualHeight - WindowRoot.ActualHeight; |
||||
|
return top < 0 ? 0 : top; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return Top; |
||||
|
} |
||||
|
|
||||
|
private void SetWindowState(WindowState state) |
||||
|
{ |
||||
|
switch (state) |
||||
|
{ |
||||
|
case WindowState.Closed: |
||||
|
{ |
||||
|
ExecuteClose(); |
||||
|
break; |
||||
|
} |
||||
|
case WindowState.Open: |
||||
|
{ |
||||
|
ExecuteOpen(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ExecuteClose() |
||||
|
{ |
||||
|
CancelEventArgs e = new CancelEventArgs(); |
||||
|
OnClosing(e); |
||||
|
|
||||
|
if (!e.Cancel) |
||||
|
{ |
||||
|
if (!_dialogResult.HasValue) |
||||
|
_dialogResult = false; |
||||
|
|
||||
|
OnClosed(EventArgs.Empty); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
CancelClose(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void CancelClose() |
||||
|
{ |
||||
|
_dialogResult = null; //when the close is cancelled, DialogResult should be null
|
||||
|
|
||||
|
_ignorePropertyChanged = true; |
||||
|
WindowState = WindowState.Open; //now reset the window state to open because the close was cancelled
|
||||
|
_ignorePropertyChanged = false; |
||||
|
} |
||||
|
|
||||
|
private void ExecuteOpen() |
||||
|
{ |
||||
|
_dialogResult = null; //reset the dialogResult to null each time the window is opened
|
||||
|
|
||||
|
if (WindowStartupLocation == Controls.WindowStartupLocation.Center) |
||||
|
CenterChildWindow(); |
||||
|
|
||||
|
BringToFront(); |
||||
|
} |
||||
|
|
||||
|
private void BringToFront() |
||||
|
{ |
||||
|
int index = 0; |
||||
|
|
||||
|
if (_parentContainer != null) |
||||
|
index = (int)_parentContainer.GetValue(Canvas.ZIndexProperty); |
||||
|
|
||||
|
SetValue(Canvas.ZIndexProperty, ++index); |
||||
|
|
||||
|
if (IsModal) |
||||
|
Canvas.SetZIndex(_modalLayerPanel, index - 2); |
||||
|
} |
||||
|
|
||||
|
private void CenterChildWindow() |
||||
|
{ |
||||
|
if (_parentContainer != null) |
||||
|
{ |
||||
|
Left = (_parentContainer.ActualWidth - WindowRoot.ActualWidth) / 2.0; |
||||
|
Top = (_parentContainer.ActualHeight - WindowRoot.ActualHeight) / 2.0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void ShowModalLayer() |
||||
|
{ |
||||
|
if (!DesignerProperties.GetIsInDesignMode(this)) |
||||
|
{ |
||||
|
if (!_modalLayerPanel.Children.Contains(_modalLayer)) |
||||
|
_modalLayerPanel.Children.Add(_modalLayer); |
||||
|
|
||||
|
_modalLayer.Visibility = System.Windows.Visibility.Visible; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void HideModalLayer() |
||||
|
{ |
||||
|
_modalLayer.Visibility = System.Windows.Visibility.Collapsed; |
||||
|
} |
||||
|
|
||||
|
private void ProcessMove(double x, double y) |
||||
|
{ |
||||
|
_moveTransform.X += x; |
||||
|
_moveTransform.Y += y; |
||||
|
|
||||
|
InvalidateArrange(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Private
|
||||
|
|
||||
|
#region Public
|
||||
|
|
||||
|
public void Show() |
||||
|
{ |
||||
|
WindowState = WindowState.Open; |
||||
|
} |
||||
|
|
||||
|
public void Close() |
||||
|
{ |
||||
|
WindowState = WindowState.Closed; |
||||
|
} |
||||
|
|
||||
|
#endregion //Public
|
||||
|
|
||||
|
#endregion //Methods
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Occurs when the ChildWindow is closed.
|
||||
|
/// </summary>
|
||||
|
public event EventHandler Closed; |
||||
|
protected virtual void OnClosed(EventArgs e) |
||||
|
{ |
||||
|
if (Closed != null) |
||||
|
Closed(this, e); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Occurs when the ChildWindow is closing.
|
||||
|
/// </summary>
|
||||
|
public event EventHandler<CancelEventArgs> Closing; |
||||
|
protected virtual void OnClosing(CancelEventArgs e) |
||||
|
{ |
||||
|
if (Closing != null) |
||||
|
Closing(this, e); |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public enum WindowStartupLocation |
||||
|
{ |
||||
|
Center, |
||||
|
Manual |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public enum WindowState |
||||
|
{ |
||||
|
Closed, |
||||
|
Open |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,211 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls"> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="WindowDarkBrush" 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="WindowBackgroundBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFffffff"/> |
||||
|
<GradientStop Offset="0.479" Color="#FFf4f5f6"/> |
||||
|
<GradientStop Offset="1" Color="#FFd0d6db"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="WindowButtonHoverBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFb5bdc8"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF8399a9"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF718597"/> |
||||
|
<GradientStop Offset="0.906" Color="#FFb9c1ca"/> |
||||
|
<GradientStop Offset="1" Color="#FFb9c1ca"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="WindowButtonPressedBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FF6b7c8d"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF4d606f"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF465460"/> |
||||
|
<GradientStop Offset="0.906" Color="#FF262d33"/> |
||||
|
<GradientStop Offset="1" Color="#FF262d33"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<Style x:Key="WindowCloseButtonStyle" TargetType="Button"> |
||||
|
<Setter Property="Foreground" Value="#FF000000"/> |
||||
|
<Setter Property="Padding" Value="3"/> |
||||
|
<Setter Property="BorderThickness" Value="1"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="Button"> |
||||
|
<Grid> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="CommonStates"> |
||||
|
<VisualState x:Name="Normal"/> |
||||
|
<VisualState x:Name="MouseOver"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource WindowButtonHoverBrush}"></DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Pressed"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource WindowButtonPressedBrush}"></DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
<Border x:Name="Background" CornerRadius="0,0,2,0" Background="{StaticResource WindowDarkBrush}"> |
||||
|
<Border Margin="1,0,1,1" BorderBrush="#59FFFFFF" BorderThickness="1" CornerRadius="0,0,1,0"/> |
||||
|
</Border> |
||||
|
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> |
||||
|
<Path x:Name="path" |
||||
|
Height="6" |
||||
|
Width="7" |
||||
|
Stretch="Fill" |
||||
|
Opacity="1" |
||||
|
Data="M 2,6 C2,6 3,6 3,6 3,6 3,5 3,5 3,5 4,5 4,5 4,5 4,6 4,6 4,6 5,6 5,6 5,6 7,6 7,6 7,6 7,5 7,5 7,5 6,5 6,5 6,5 6,4 6,4 6,4 5,4 5,4 5,4 5,2 5,2 5,2 6,2 6,2 6,2 6,1 6,1 6,1 7,1 7,1 7,1 7,0 7,0 7,0 5,0 5,0 5,0 4,0 4,0 4,0 4,1 4,1 4,1 3,1 3,1 3,1 3,0 3,0 3,0 2,0 2,0 2,0 0,0 0,0 0,0 0,1 0,1 0,1 1,1 1,1 1,1 1,2 1,2 1,2 2,2 2,2 2,2 2,4 2,4 2,4 1,4 1,4 1,4 1,5 1,5 1,5 0,5 0,5 0,5 0,6 0,6 0,6 2,6 2,6 z" |
||||
|
Fill="White" Margin="0,0,0,1" Visibility="Collapsed" /> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- ChildWindow --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<SolidColorBrush x:Key="ChildWindowMainBrushColor" Color="#FF3C688D"/> |
||||
|
<LinearGradientBrush x:Key="BorderBrush" EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#7FFFFFFF" Offset="0.05"/> |
||||
|
<GradientStop Color="#B2FFFFFF" Offset="0.07"/> |
||||
|
<GradientStop Color="#00FFFFFF" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:ChildWindow}"> |
||||
|
<Setter Property="Background" Value="#FFFFFFFF"/> |
||||
|
<Setter Property="BorderBrush" Value="{StaticResource WindowDarkBrush}" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="CaptionForeground" Value="#FF000000" /> |
||||
|
<Setter Property="CloseButtonStyle" Value="{StaticResource WindowCloseButtonStyle}" /> |
||||
|
<Setter Property="HorizontalAlignment" Value="Left" /> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
||||
|
<Setter Property="IsTabStop" Value="False" /> |
||||
|
<Setter Property="VerticalAlignment" Value="Top" /> |
||||
|
<Setter Property="VerticalContentAlignment" Value="Top" /> |
||||
|
<Setter Property="WindowBorderBrush" Value="{StaticResource WindowDarkBrush}" /> |
||||
|
<Setter Property="WindowBackground" Value="{StaticResource WindowBackgroundBrush}" /> |
||||
|
<Setter Property="WindowOpacity" Value="1.0" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:ChildWindow}"> |
||||
|
<Grid x:Name="Root"> |
||||
|
<Grid.Resources> |
||||
|
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> |
||||
|
<Style x:Key="FocusVisualStyle" TargetType="Control"> |
||||
|
<Setter Property="BorderBrush" Value="Black"/> |
||||
|
<Setter Property="Background" Value="Transparent"/> |
||||
|
<Setter Property="Margin" Value="-1"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate> |
||||
|
<Rectangle Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" Margin="{TemplateBinding Margin}" StrokeDashArray="4 3" StrokeThickness="0.5"> |
||||
|
<Rectangle.RenderTransform> |
||||
|
<TranslateTransform X="{Binding Left}" Y="{Binding Top}"/> |
||||
|
</Rectangle.RenderTransform> |
||||
|
</Rectangle> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
</Grid.Resources> |
||||
|
|
||||
|
<Grid x:Name="PART_WindowRoot" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="{TemplateBinding MinWidth}" MinHeight="{TemplateBinding MinHeight}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" > |
||||
|
<Grid.RenderTransform> |
||||
|
<TransformGroup> |
||||
|
<ScaleTransform /> |
||||
|
<SkewTransform /> |
||||
|
<RotateTransform /> |
||||
|
<TranslateTransform /> |
||||
|
</TransformGroup> |
||||
|
</Grid.RenderTransform> |
||||
|
|
||||
|
<!-- Borders --> |
||||
|
<Grid x:Name="WindowGrid"> |
||||
|
<Border BorderBrush="{TemplateBinding WindowBorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5,5,0,0" Opacity="{TemplateBinding WindowOpacity}"/> |
||||
|
<Grid Margin="0" Background="{x:Null}"> |
||||
|
<Border x:Name="WindowBorder" Margin="1,1,1,1" Background="{TemplateBinding WindowBackground}" CornerRadius="4,4,0,0" Opacity="{TemplateBinding WindowOpacity}"/> |
||||
|
<Border BorderBrush="White" BorderThickness="1" CornerRadius="4,4,0,0" Margin="1" Opacity="0.7"/> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" MinHeight="26"/> |
||||
|
<RowDefinition /> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<!-- Content Border --> |
||||
|
<Grid Margin="6,0,6,6" x:Name="ContentGrid" Grid.Row="1"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Border BorderBrush="#FFFFFFFF" BorderThickness="1" CornerRadius="1"/> |
||||
|
<Border Margin="1" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0.1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"> |
||||
|
|
||||
|
<ContentPresenter x:Name="Content" Content="{TemplateBinding Content}" |
||||
|
ContentTemplate="{TemplateBinding ContentTemplate}" /> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
|
||||
|
<!-- Header --> |
||||
|
<Border x:Name="PART_DragWidget" Background="Transparent" Grid.Column="1" CornerRadius="5,5,0,0" Margin="1,1,1,0"> |
||||
|
<Grid> |
||||
|
<Grid x:Name="CaptionHeader" Margin="1,1,105,0" VerticalAlignment="Center"> |
||||
|
<!-- Caption --> |
||||
|
<ContentControl x:Name="Caption" Margin="5,0,0,0" IsTabStop="False" HorizontalAlignment="Stretch" |
||||
|
Content="{TemplateBinding Caption}" |
||||
|
Foreground="{TemplateBinding CaptionForeground}"/> |
||||
|
|
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
|
||||
|
<!-- Buttons --> |
||||
|
<Border BorderBrush="#A5FFFFFF" BorderThickness="1,0,1,1" CornerRadius="0,0,3,3" VerticalAlignment="Top" Margin="0,1,7,0" HorizontalAlignment="Right"> |
||||
|
<Button x:Name="PART_CloseButton" Style="{TemplateBinding CloseButtonStyle}" Visibility="{TemplateBinding CloseButtonVisibility}" Height="17" Width="43" IsTabStop="False"> |
||||
|
<Path Height="10" HorizontalAlignment="Center" VerticalAlignment="Center" Width="12" Fill="#E4FFFFFF" Stretch="Fill" Stroke="#FF535666" |
||||
|
Data="M0.5,0.5 L4.5178828,0.5 L6.0620003,3.125 L7.4936447,0.5 L11.5,0.5 L11.5,1.5476431 L8.7425003,6.1201854 L11.5,10.359666 L11.5,11.5 L7.4941902,11.5 L6.0620003,8.8740005 L4.5172949,11.5 L0.5,11.5 L0.5,10.43379 L3.3059995,6.1201582 L0.5,1.4676378 L0.5,0.5 z"/> |
||||
|
</Button> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="WindowState" Value="Closed"> |
||||
|
<Setter Property="Visibility" Value="Collapsed" /> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,208 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Chromes |
||||
|
{ |
||||
|
public class ButtonChrome : Control |
||||
|
{ |
||||
|
#region CornerRadius
|
||||
|
|
||||
|
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ButtonChrome), new UIPropertyMetadata(default(CornerRadius), new PropertyChangedCallback(OnCornerRadiusChanged))); |
||||
|
public CornerRadius CornerRadius |
||||
|
{ |
||||
|
get { return (CornerRadius)GetValue(CornerRadiusProperty); } |
||||
|
set { SetValue(CornerRadiusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnCornerRadiusChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnCornerRadiusChanged((CornerRadius)e.OldValue, (CornerRadius)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnCornerRadiusChanged(CornerRadius oldValue, CornerRadius newValue) |
||||
|
{ |
||||
|
//we always want the InnerBorderRadius to be one less than the CornerRadius
|
||||
|
CornerRadius newInnerCornerRadius = new CornerRadius(Math.Max(0, newValue.TopLeft - 1), |
||||
|
Math.Max(0, newValue.TopRight - 1), |
||||
|
Math.Max(0, newValue.BottomRight - 1), |
||||
|
Math.Max(0, newValue.BottomLeft - 1)); |
||||
|
|
||||
|
InnerCornerRadius = newInnerCornerRadius; |
||||
|
} |
||||
|
|
||||
|
#endregion //CornerRadius
|
||||
|
|
||||
|
#region InnerCornerRadius
|
||||
|
|
||||
|
public static readonly DependencyProperty InnerCornerRadiusProperty = DependencyProperty.Register("InnerCornerRadius", typeof(CornerRadius), typeof(ButtonChrome), new UIPropertyMetadata(default(CornerRadius), new PropertyChangedCallback(OnInnerCornerRadiusChanged))); |
||||
|
public CornerRadius InnerCornerRadius |
||||
|
{ |
||||
|
get { return (CornerRadius)GetValue(InnerCornerRadiusProperty); } |
||||
|
set { SetValue(InnerCornerRadiusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnInnerCornerRadiusChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnInnerCornerRadiusChanged((CornerRadius)e.OldValue, (CornerRadius)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnInnerCornerRadiusChanged(CornerRadius oldValue, CornerRadius newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //InnerCornerRadius
|
||||
|
|
||||
|
#region RenderChecked
|
||||
|
|
||||
|
public static readonly DependencyProperty RenderCheckedProperty = DependencyProperty.Register("RenderChecked", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderCheckedChanged)); |
||||
|
public bool RenderChecked |
||||
|
{ |
||||
|
get { return (bool)GetValue(RenderCheckedProperty); } |
||||
|
set { SetValue(RenderCheckedProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRenderCheckedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnRenderCheckedChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRenderCheckedChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //RenderChecked
|
||||
|
|
||||
|
#region RenderEnabled
|
||||
|
|
||||
|
public static readonly DependencyProperty RenderEnabledProperty = DependencyProperty.Register("RenderEnabled", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(true, OnRenderEnabledChanged)); |
||||
|
public bool RenderEnabled |
||||
|
{ |
||||
|
get { return (bool)GetValue(RenderEnabledProperty); } |
||||
|
set { SetValue(RenderEnabledProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRenderEnabledChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnRenderEnabledChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRenderEnabledChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //RenderEnabled
|
||||
|
|
||||
|
#region RenderFocused
|
||||
|
|
||||
|
public static readonly DependencyProperty RenderFocusedProperty = DependencyProperty.Register("RenderFocused", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderFocusedChanged)); |
||||
|
public bool RenderFocused |
||||
|
{ |
||||
|
get { return (bool)GetValue(RenderFocusedProperty); } |
||||
|
set { SetValue(RenderFocusedProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRenderFocusedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnRenderFocusedChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRenderFocusedChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //RenderFocused
|
||||
|
|
||||
|
#region RenderMouseOver
|
||||
|
|
||||
|
public static readonly DependencyProperty RenderMouseOverProperty = DependencyProperty.Register("RenderMouseOver", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderMouseOverChanged)); |
||||
|
public bool RenderMouseOver |
||||
|
{ |
||||
|
get { return (bool)GetValue(RenderMouseOverProperty); } |
||||
|
set { SetValue(RenderMouseOverProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRenderMouseOverChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnRenderMouseOverChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRenderMouseOverChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //RenderMouseOver
|
||||
|
|
||||
|
#region RenderNormal
|
||||
|
|
||||
|
public static readonly DependencyProperty RenderNormalProperty = DependencyProperty.Register("RenderNormal", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(true, OnRenderNormalChanged)); |
||||
|
public bool RenderNormal |
||||
|
{ |
||||
|
get { return (bool)GetValue(RenderNormalProperty); } |
||||
|
set { SetValue(RenderNormalProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRenderNormalChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnRenderNormalChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRenderNormalChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //RenderNormal
|
||||
|
|
||||
|
#region RenderPressed
|
||||
|
|
||||
|
public static readonly DependencyProperty RenderPressedProperty = DependencyProperty.Register("RenderPressed", typeof(bool), typeof(ButtonChrome), new UIPropertyMetadata(false, OnRenderPressedChanged)); |
||||
|
public bool RenderPressed |
||||
|
{ |
||||
|
get { return (bool)GetValue(RenderPressedProperty); } |
||||
|
set { SetValue(RenderPressedProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRenderPressedChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ButtonChrome buttonChrome = o as ButtonChrome; |
||||
|
if (buttonChrome != null) |
||||
|
buttonChrome.OnRenderPressedChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRenderPressedChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
// TODO: Add your property changed side-effects. Descendants can override as well.
|
||||
|
} |
||||
|
|
||||
|
#endregion //RenderPressed
|
||||
|
|
||||
|
#region Contsructors
|
||||
|
|
||||
|
static ButtonChrome() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonChrome), new FrameworkPropertyMetadata(typeof(ButtonChrome))); |
||||
|
} |
||||
|
|
||||
|
#endregion //Contsructors
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,266 @@ |
|||||
|
<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:local="clr-namespace:Microsoft.Windows.Controls" > |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- ButtonChrome --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<CornerRadius x:Key="ControlOuterBorderCornerRadius">2.75</CornerRadius> |
||||
|
<CornerRadius x:Key="ControlInnerBorderCornerRadius">1.75</CornerRadius> |
||||
|
|
||||
|
<!-- Normal --> |
||||
|
<SolidColorBrush x:Key="ControlOuterBorder_Normal" Color="#FF707070" /> |
||||
|
<LinearGradientBrush x:Key="ControlInnerBorder_Normal" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FAFFFFFF" Offset="0"/> |
||||
|
<GradientStop Color="#85FFFFFF" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
<LinearGradientBrush x:Key="ControlBackground_Normal" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#F3F3F3" Offset="0"/> |
||||
|
<GradientStop Color="#EBEBEB" Offset="0.5"/> |
||||
|
<GradientStop Color="#DDDDDD" Offset="0.5"/> |
||||
|
<GradientStop Color="#CDCDCD" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<!--Mouse Over--> |
||||
|
<SolidColorBrush x:Key="ControlOuterBorder_MouseOver" Color="#3C7FB1" /> |
||||
|
<LinearGradientBrush x:Key="ControlInnerBorder_MouseOver" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FAFFFFFF" Offset="0"/> |
||||
|
<GradientStop Color="#85FFFFFF" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
<LinearGradientBrush x:Key="ControlBackground_MouseOver" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FFEAF6FD" Offset="0"/> |
||||
|
<GradientStop Color="#FFD9F0FC" Offset="0.50"/> |
||||
|
<GradientStop Color="#FFBEE6FD" Offset="0.50"/> |
||||
|
<GradientStop Color="#FFA7D9F5" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<!-- Pressed --> |
||||
|
<SolidColorBrush x:Key="ControlOuterBorder_Pressed" Color="#2C628B" /> |
||||
|
<LinearGradientBrush x:Key="ControlInnerBorder_Pressed" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FAFFFFFF" Offset="0"/> |
||||
|
<GradientStop Color="#85FFFFFF" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
<LinearGradientBrush x:Key="ControlBackground_Pressed" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#C2E4F6" Offset="0.5"/> |
||||
|
<GradientStop Color="#ABDAF3" Offset="0.5"/> |
||||
|
<GradientStop Color="#90CBEB" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<!-- Focused --> |
||||
|
<SolidColorBrush x:Key="ControlOuterBorder_Focused" Color="#FF707070" /> |
||||
|
<SolidColorBrush x:Key="ControlInnerBorder_Focused" Color="#F900CCFF" /> |
||||
|
<LinearGradientBrush x:Key="ControlBackground_Focused" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FFEAF6FD" Offset="0"/> |
||||
|
<GradientStop Color="#FFD9F0FC" Offset="0.50"/> |
||||
|
<GradientStop Color="#FFBEE6FD" Offset="0.50"/> |
||||
|
<GradientStop Color="#FFA7D9F5" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<!-- Disabled --> |
||||
|
<SolidColorBrush x:Key="ControlOuterBorder_Disabled" Color="#ADB2B5" /> |
||||
|
<LinearGradientBrush x:Key="ControlInnerBorder_Disabled" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FAFFFFFF" Offset="0"/> |
||||
|
<GradientStop Color="#85FFFFFF" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
<SolidColorBrush x:Key="ControlBackground_Disabled" Color="#F4F4F4" /> |
||||
|
|
||||
|
<Style TargetType="{x:Type chrome:ButtonChrome}"> |
||||
|
<Setter Property="IsTabStop" Value="False" /> |
||||
|
<Setter Property="SnapsToDevicePixels" Value="True" /> |
||||
|
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> |
||||
|
<Setter Property="Background" Value="{StaticResource ControlBackground_Normal}" /> |
||||
|
<Setter Property="BorderBrush" Value="{StaticResource ControlOuterBorder_Normal}" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="CornerRadius" Value="{StaticResource ControlOuterBorderCornerRadius}" /> |
||||
|
<Setter Property="InnerCornerRadius" Value="{StaticResource ControlInnerBorderCornerRadius}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type chrome:ButtonChrome}"> |
||||
|
<Grid> |
||||
|
|
||||
|
<Border x:Name="OuterBorder" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}"> |
||||
|
<Border x:Name="InnerBorder" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding InnerCornerRadius}" BorderBrush="{StaticResource ControlInnerBorder_Normal}" /> |
||||
|
</Border> |
||||
|
|
||||
|
<Border x:Name="MouseOverVisual" Opacity="0" Visibility="Collapsed" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{StaticResource ControlOuterBorder_MouseOver}" Background="{StaticResource ControlBackground_MouseOver}"> |
||||
|
<Border x:Name="MouseOverInnerVisual" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding InnerCornerRadius}" BorderBrush="{StaticResource ControlInnerBorder_MouseOver}" /> |
||||
|
</Border> |
||||
|
<Border x:Name="PressedVisual" Opacity="0" Visibility="Collapsed" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{StaticResource ControlOuterBorder_Pressed}" Background="{StaticResource ControlBackground_Pressed}"> |
||||
|
<Border x:Name="PressedInnerVisual" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding InnerCornerRadius}" BorderBrush="{StaticResource ControlInnerBorder_Pressed}" /> |
||||
|
</Border> |
||||
|
|
||||
|
<Border x:Name="FocusVisual" Opacity="0" Visibility="Collapsed" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{StaticResource ControlOuterBorder_Focused}" Background="{StaticResource ControlBackground_Focused}"> |
||||
|
<Border x:Name="FocusInnerVisual" BorderThickness="1" CornerRadius="{TemplateBinding InnerCornerRadius}" BorderBrush="{StaticResource ControlInnerBorder_Focused}" /> |
||||
|
</Border> |
||||
|
|
||||
|
</Grid> |
||||
|
<ControlTemplate.Triggers> |
||||
|
|
||||
|
<!-- If button is disabled, not checked, and is rendered normal --> |
||||
|
<MultiTrigger> |
||||
|
<MultiTrigger.Conditions> |
||||
|
<Condition Property="RenderEnabled" Value="False" /> |
||||
|
<Condition Property="RenderChecked" Value="False" /> |
||||
|
</MultiTrigger.Conditions> |
||||
|
<Setter TargetName="OuterBorder" Property="BorderBrush" Value="{StaticResource ControlOuterBorder_Disabled}" /> |
||||
|
<Setter TargetName="InnerBorder" Property="BorderBrush" Value="{StaticResource ControlInnerBorder_Disabled}" /> |
||||
|
<Setter TargetName="OuterBorder" Property="Background" Value="{StaticResource ControlBackground_Disabled}" /> |
||||
|
</MultiTrigger> |
||||
|
|
||||
|
<!-- if button is enabled and pressed --> |
||||
|
<MultiTrigger> |
||||
|
<MultiTrigger.Conditions> |
||||
|
<Condition Property="RenderEnabled" Value="True" /> |
||||
|
<Condition Property="RenderPressed" Value="True" /> |
||||
|
</MultiTrigger.Conditions> |
||||
|
<MultiTrigger.EnterActions> |
||||
|
<BeginStoryboard> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PressedVisual" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PressedVisual" Storyboard.TargetProperty="Opacity"> |
||||
|
<LinearDoubleKeyFrame KeyTime="00:00:00.050" Value="1" /> |
||||
|
</DoubleAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</BeginStoryboard> |
||||
|
</MultiTrigger.EnterActions> |
||||
|
<MultiTrigger.ExitActions> |
||||
|
<BeginStoryboard> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PressedVisual" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00.115"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Collapsed</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="PressedVisual" Storyboard.TargetProperty="Opacity"> |
||||
|
<LinearDoubleKeyFrame KeyTime="00:00:00.115" Value="0" /> |
||||
|
</DoubleAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</BeginStoryboard> |
||||
|
</MultiTrigger.ExitActions> |
||||
|
</MultiTrigger> |
||||
|
|
||||
|
<!-- if button is enabled, is not checked, the mouse is over, and not pressed --> |
||||
|
<MultiTrigger> |
||||
|
<MultiTrigger.Conditions> |
||||
|
<Condition Property="RenderEnabled" Value="True" /> |
||||
|
<Condition Property="RenderChecked" Value="False" /> |
||||
|
<Condition Property="RenderMouseOver" Value="True" /> |
||||
|
<Condition Property="RenderPressed" Value="False" /> |
||||
|
</MultiTrigger.Conditions> |
||||
|
<MultiTrigger.EnterActions> |
||||
|
<BeginStoryboard> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MouseOverVisual" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MouseOverVisual" Storyboard.TargetProperty="Opacity"> |
||||
|
<LinearDoubleKeyFrame KeyTime="00:00:00.115" Value="1" /> |
||||
|
</DoubleAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</BeginStoryboard> |
||||
|
</MultiTrigger.EnterActions> |
||||
|
<MultiTrigger.ExitActions> |
||||
|
<BeginStoryboard> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MouseOverVisual" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00.150"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Collapsed</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MouseOverVisual" Storyboard.TargetProperty="Opacity"> |
||||
|
<LinearDoubleKeyFrame KeyTime="00:00:00.150" Value="0" /> |
||||
|
</DoubleAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</BeginStoryboard> |
||||
|
</MultiTrigger.ExitActions> |
||||
|
</MultiTrigger> |
||||
|
|
||||
|
<!-- if button is enabled, checked, he mouse is not over, and it is not pressed --> |
||||
|
<MultiTrigger> |
||||
|
<MultiTrigger.Conditions> |
||||
|
<Condition Property="RenderEnabled" Value="True" /> |
||||
|
<Condition Property="RenderChecked" Value="True" /> |
||||
|
<Condition Property="RenderMouseOver" Value="False" /> |
||||
|
<Condition Property="RenderPressed" Value="False" /> |
||||
|
</MultiTrigger.Conditions> |
||||
|
<Setter TargetName="OuterBorder" Property="BorderBrush" Value="{StaticResource ControlOuterBorder_Pressed}" /> |
||||
|
<Setter TargetName="InnerBorder" Property="BorderBrush" Value="{StaticResource ControlInnerBorder_Pressed}" /> |
||||
|
<Setter TargetName="OuterBorder" Property="Background" Value="{StaticResource ControlBackground_Pressed}" /> |
||||
|
</MultiTrigger> |
||||
|
|
||||
|
<!-- if button is focused, is enabled, not pressed, and the mouse is not over --> |
||||
|
<MultiTrigger> |
||||
|
<MultiTrigger.Conditions> |
||||
|
<Condition Property="RenderFocused" Value="True" /> |
||||
|
<Condition Property="RenderEnabled" Value="True" /> |
||||
|
<Condition Property="RenderPressed" Value="False" /> |
||||
|
<Condition Property="RenderMouseOver" Value="False" /> |
||||
|
</MultiTrigger.Conditions> |
||||
|
<MultiTrigger.EnterActions> |
||||
|
<BeginStoryboard> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Opacity"> |
||||
|
<LinearDoubleKeyFrame KeyTime="00:00:00.25" Value="1" /> |
||||
|
</DoubleAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</BeginStoryboard> |
||||
|
</MultiTrigger.EnterActions> |
||||
|
<MultiTrigger.ExitActions> |
||||
|
<BeginStoryboard> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00.115"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Collapsed</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Opacity"> |
||||
|
<LinearDoubleKeyFrame KeyTime="00:00:00.115" Value="0" /> |
||||
|
</DoubleAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</BeginStoryboard> |
||||
|
</MultiTrigger.ExitActions> |
||||
|
</MultiTrigger> |
||||
|
|
||||
|
<!-- if not rendered normally --> |
||||
|
<MultiTrigger> |
||||
|
<MultiTrigger.Conditions> |
||||
|
<Condition Property="RenderNormal" Value="False" /> |
||||
|
<Condition Property="RenderChecked" Value="False" /> |
||||
|
</MultiTrigger.Conditions> |
||||
|
<Setter TargetName="OuterBorder" Property="BorderBrush" Value="Transparent" /> |
||||
|
<Setter TargetName="InnerBorder" Property="BorderBrush" Value="{x:Null}" /> |
||||
|
<Setter TargetName="OuterBorder" Property="Background" Value="Transparent" /> |
||||
|
</MultiTrigger> |
||||
|
|
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,365 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
using Microsoft.Windows.Controls.Primitives; |
||||
|
using Microsoft.Windows.Controls.Core.Utilities; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class ColorCanvas : Control |
||||
|
{ |
||||
|
#region Private Members
|
||||
|
|
||||
|
private TranslateTransform _colorShadeSelectorTransform = new TranslateTransform(); |
||||
|
private Canvas _colorShadingCanvas; |
||||
|
private Canvas _colorShadeSelector; |
||||
|
private ColorSpectrumSlider _spectrumSlider; |
||||
|
private Point? _currentColorPosition; |
||||
|
private bool _surpressPropertyChanged; |
||||
|
|
||||
|
#endregion //Private Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region SelectedColor
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorCanvas), new FrameworkPropertyMetadata(Colors.Black, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedColorChanged)); |
||||
|
public Color SelectedColor |
||||
|
{ |
||||
|
get { return (Color)GetValue(SelectedColorProperty); } |
||||
|
set { SetValue(SelectedColorProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnSelectedColorChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorCanvas colorCanvas = o as ColorCanvas; |
||||
|
if (colorCanvas != null) |
||||
|
colorCanvas.OnSelectedColorChanged((Color)e.OldValue, (Color)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnSelectedColorChanged(Color oldValue, Color newValue) |
||||
|
{ |
||||
|
HexadecimalString = newValue.ToString(); |
||||
|
UpdateRGBValues(newValue); |
||||
|
UpdateColorShadeSelectorPosition(newValue); |
||||
|
|
||||
|
RoutedPropertyChangedEventArgs<Color> args = new RoutedPropertyChangedEventArgs<Color>(oldValue, newValue); |
||||
|
args.RoutedEvent = SelectedColorChangedEvent; |
||||
|
RaiseEvent(args); |
||||
|
} |
||||
|
|
||||
|
#endregion //SelectedColor
|
||||
|
|
||||
|
#region RGB
|
||||
|
|
||||
|
#region A
|
||||
|
|
||||
|
public static readonly DependencyProperty AProperty = DependencyProperty.Register("A", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)255, OnAChanged)); |
||||
|
public byte A |
||||
|
{ |
||||
|
get { return (byte)GetValue(AProperty); } |
||||
|
set { SetValue(AProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnAChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorCanvas colorCanvas = o as ColorCanvas; |
||||
|
if (colorCanvas != null) |
||||
|
colorCanvas.OnAChanged((byte)e.OldValue, (byte)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnAChanged(byte oldValue, byte newValue) |
||||
|
{ |
||||
|
if (!_surpressPropertyChanged) |
||||
|
UpdateSelectedColor(); |
||||
|
} |
||||
|
|
||||
|
#endregion //A
|
||||
|
|
||||
|
#region R
|
||||
|
|
||||
|
public static readonly DependencyProperty RProperty = DependencyProperty.Register("R", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)0, OnRChanged)); |
||||
|
public byte R |
||||
|
{ |
||||
|
get { return (byte)GetValue(RProperty); } |
||||
|
set { SetValue(RProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorCanvas colorCanvas = o as ColorCanvas; |
||||
|
if (colorCanvas != null) |
||||
|
colorCanvas.OnRChanged((byte)e.OldValue, (byte)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRChanged(byte oldValue, byte newValue) |
||||
|
{ |
||||
|
if (!_surpressPropertyChanged) |
||||
|
UpdateSelectedColor(); |
||||
|
} |
||||
|
|
||||
|
#endregion //R
|
||||
|
|
||||
|
#region G
|
||||
|
|
||||
|
public static readonly DependencyProperty GProperty = DependencyProperty.Register("G", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)0, OnGChanged)); |
||||
|
public byte G |
||||
|
{ |
||||
|
get { return (byte)GetValue(GProperty); } |
||||
|
set { SetValue(GProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnGChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorCanvas colorCanvas = o as ColorCanvas; |
||||
|
if (colorCanvas != null) |
||||
|
colorCanvas.OnGChanged((byte)e.OldValue, (byte)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnGChanged(byte oldValue, byte newValue) |
||||
|
{ |
||||
|
if (!_surpressPropertyChanged) |
||||
|
UpdateSelectedColor(); |
||||
|
} |
||||
|
|
||||
|
#endregion //G
|
||||
|
|
||||
|
#region B
|
||||
|
|
||||
|
public static readonly DependencyProperty BProperty = DependencyProperty.Register("B", typeof(byte), typeof(ColorCanvas), new UIPropertyMetadata((byte)0, OnBChanged)); |
||||
|
public byte B |
||||
|
{ |
||||
|
get { return (byte)GetValue(BProperty); } |
||||
|
set { SetValue(BProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnBChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorCanvas colorCanvas = o as ColorCanvas; |
||||
|
if (colorCanvas != null) |
||||
|
colorCanvas.OnBChanged((byte)e.OldValue, (byte)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnBChanged(byte oldValue, byte newValue) |
||||
|
{ |
||||
|
if (!_surpressPropertyChanged) |
||||
|
UpdateSelectedColor(); |
||||
|
} |
||||
|
|
||||
|
#endregion //B
|
||||
|
|
||||
|
#endregion //RGB
|
||||
|
|
||||
|
#region HexadecimalString
|
||||
|
|
||||
|
public static readonly DependencyProperty HexadecimalStringProperty = DependencyProperty.Register("HexadecimalString", typeof(string), typeof(ColorCanvas), new UIPropertyMetadata("#FFFFFFFF", OnHexadecimalStringChanged)); |
||||
|
public string HexadecimalString |
||||
|
{ |
||||
|
get { return (string)GetValue(HexadecimalStringProperty); } |
||||
|
set { SetValue(HexadecimalStringProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnHexadecimalStringChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorCanvas colorCanvas = o as ColorCanvas; |
||||
|
if (colorCanvas != null) |
||||
|
colorCanvas.OnHexadecimalStringChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnHexadecimalStringChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
if (!SelectedColor.ToString().Equals(newValue)) |
||||
|
UpdateSelectedColor((Color)ColorConverter.ConvertFromString(newValue)); |
||||
|
} |
||||
|
|
||||
|
#endregion //HexadecimalString
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static ColorCanvas() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorCanvas), new FrameworkPropertyMetadata(typeof(ColorCanvas))); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_colorShadingCanvas = (Canvas)GetTemplateChild("PART_ColorShadingCanvas"); |
||||
|
_colorShadingCanvas.MouseLeftButtonDown += ColorShadingCanvas_MouseLeftButtonDown; |
||||
|
_colorShadingCanvas.MouseLeftButtonUp += ColorShadingCanvas_MouseLeftButtonUp; |
||||
|
_colorShadingCanvas.MouseMove += ColorShadingCanvas_MouseMove; |
||||
|
_colorShadingCanvas.SizeChanged += ColorShadingCanvas_SizeChanged; |
||||
|
|
||||
|
_colorShadeSelector = (Canvas)GetTemplateChild("PART_ColorShadeSelector"); |
||||
|
_colorShadeSelector.RenderTransform = _colorShadeSelectorTransform; |
||||
|
|
||||
|
_spectrumSlider = (ColorSpectrumSlider)GetTemplateChild("PART_SpectrumSlider"); |
||||
|
_spectrumSlider.ValueChanged += SpectrumSlider_ValueChanged; |
||||
|
|
||||
|
UpdateRGBValues(SelectedColor); |
||||
|
UpdateColorShadeSelectorPosition(SelectedColor); |
||||
|
} |
||||
|
|
||||
|
protected override void OnPreviewKeyDown(KeyEventArgs e) |
||||
|
{ |
||||
|
//hitting enter on textbox will update value of underlying source
|
||||
|
if (e.Key == Key.Enter && e.OriginalSource is TextBox) |
||||
|
{ |
||||
|
BindingExpression be = ((TextBox)e.OriginalSource).GetBindingExpression(TextBox.TextProperty); |
||||
|
be.UpdateSource(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void ColorShadingCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
Point p = e.GetPosition(_colorShadingCanvas); |
||||
|
UpdateColorShadeSelectorPositionAndCalculateColor(p, true); |
||||
|
_colorShadingCanvas.CaptureMouse(); |
||||
|
} |
||||
|
|
||||
|
void ColorShadingCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
_colorShadingCanvas.ReleaseMouseCapture(); |
||||
|
} |
||||
|
|
||||
|
void ColorShadingCanvas_MouseMove(object sender, MouseEventArgs e) |
||||
|
{ |
||||
|
if (e.LeftButton == MouseButtonState.Pressed) |
||||
|
{ |
||||
|
Point p = e.GetPosition(_colorShadingCanvas); |
||||
|
UpdateColorShadeSelectorPositionAndCalculateColor(p, true); |
||||
|
Mouse.Synchronize(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ColorShadingCanvas_SizeChanged(object sender, SizeChangedEventArgs e) |
||||
|
{ |
||||
|
if (_currentColorPosition != null) |
||||
|
{ |
||||
|
Point _newPoint = new Point |
||||
|
{ |
||||
|
X = ((Point)_currentColorPosition).X * e.NewSize.Width, |
||||
|
Y = ((Point)_currentColorPosition).Y * e.NewSize.Height |
||||
|
}; |
||||
|
|
||||
|
UpdateColorShadeSelectorPositionAndCalculateColor(_newPoint, false); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SpectrumSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) |
||||
|
{ |
||||
|
if (_currentColorPosition != null) |
||||
|
{ |
||||
|
CalculateColor((Point)_currentColorPosition); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorCanvas)); |
||||
|
public event RoutedPropertyChangedEventHandler<Color> SelectedColorChanged |
||||
|
{ |
||||
|
add { AddHandler(SelectedColorChangedEvent, value); } |
||||
|
remove { RemoveHandler(SelectedColorChangedEvent, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void UpdateSelectedColor() |
||||
|
{ |
||||
|
SelectedColor = Color.FromArgb(A, R, G, B); |
||||
|
} |
||||
|
|
||||
|
private void UpdateSelectedColor(Color color) |
||||
|
{ |
||||
|
SelectedColor = Color.FromArgb(color.A, color.R, color.G, color.B); |
||||
|
} |
||||
|
|
||||
|
private void UpdateRGBValues(Color color) |
||||
|
{ |
||||
|
_surpressPropertyChanged = true; |
||||
|
|
||||
|
A = color.A; |
||||
|
R = color.R; |
||||
|
G = color.G; |
||||
|
B = color.B; |
||||
|
|
||||
|
_surpressPropertyChanged = false; |
||||
|
} |
||||
|
|
||||
|
private void UpdateColorShadeSelectorPositionAndCalculateColor(Point p, bool calculateColor) |
||||
|
{ |
||||
|
if (p.Y < 0) |
||||
|
p.Y = 0; |
||||
|
|
||||
|
if (p.X < 0) |
||||
|
p.X = 0; |
||||
|
|
||||
|
if (p.X > _colorShadingCanvas.ActualWidth) |
||||
|
p.X = _colorShadingCanvas.ActualWidth; |
||||
|
|
||||
|
if (p.Y > _colorShadingCanvas.ActualHeight) |
||||
|
p.Y = _colorShadingCanvas.ActualHeight; |
||||
|
|
||||
|
_colorShadeSelectorTransform.X = p.X - (_colorShadeSelector.Width / 2); |
||||
|
_colorShadeSelectorTransform.Y = p.Y - (_colorShadeSelector.Height / 2); |
||||
|
|
||||
|
p.X = p.X / _colorShadingCanvas.ActualWidth; |
||||
|
p.Y = p.Y / _colorShadingCanvas.ActualHeight; |
||||
|
|
||||
|
_currentColorPosition = p; |
||||
|
|
||||
|
if (calculateColor) |
||||
|
CalculateColor(p); |
||||
|
} |
||||
|
|
||||
|
private void UpdateColorShadeSelectorPosition(Color color) |
||||
|
{ |
||||
|
if (_spectrumSlider == null || _colorShadingCanvas == null) |
||||
|
return; |
||||
|
|
||||
|
_currentColorPosition = null; |
||||
|
|
||||
|
HsvColor hsv = ColorUtilities.ConvertRgbToHsv(color.R, color.G, color.B); |
||||
|
|
||||
|
if (!(color.R == color.G && color.R == color.B)) |
||||
|
_spectrumSlider.Value = hsv.H; |
||||
|
|
||||
|
Point p = new Point(hsv.S, 1 - hsv.V); |
||||
|
|
||||
|
_currentColorPosition = p; |
||||
|
|
||||
|
_colorShadeSelectorTransform.X = (p.X * _colorShadingCanvas.Width) - 5; |
||||
|
_colorShadeSelectorTransform.Y = (p.Y * _colorShadingCanvas.Height) - 5; |
||||
|
} |
||||
|
|
||||
|
private void CalculateColor(Point p) |
||||
|
{ |
||||
|
HsvColor hsv = new HsvColor(360 - _spectrumSlider.Value, 1, 1) { S = p.X, V = 1 - p.Y }; |
||||
|
var currentColor = ColorUtilities.ConvertHsvToRgb(hsv.H, hsv.S, hsv.V); |
||||
|
currentColor.A = A; |
||||
|
SelectedColor = currentColor; |
||||
|
HexadecimalString = SelectedColor.ToString(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Shapes; |
||||
|
using Microsoft.Windows.Controls.Core.Utilities; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
internal class ColorSpectrumSlider : Slider |
||||
|
{ |
||||
|
#region Private Members
|
||||
|
|
||||
|
private Rectangle _spectrumDisplay; |
||||
|
private LinearGradientBrush _pickerBrush; |
||||
|
|
||||
|
#endregion //Private Members
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static ColorSpectrumSlider() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSpectrumSlider), new FrameworkPropertyMetadata(typeof(ColorSpectrumSlider))); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Dependency Properties
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorSpectrumSlider), new PropertyMetadata(System.Windows.Media.Colors.Transparent)); |
||||
|
public Color SelectedColor |
||||
|
{ |
||||
|
get { return (Color)GetValue(SelectedColorProperty); } |
||||
|
set { SetValue(SelectedColorProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Dependency Properties
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_spectrumDisplay = (Rectangle)GetTemplateChild("PART_SpectrumDisplay"); |
||||
|
CreateSpectrum(); |
||||
|
OnValueChanged(Double.NaN, Value); |
||||
|
} |
||||
|
|
||||
|
protected override void OnValueChanged(double oldValue, double newValue) |
||||
|
{ |
||||
|
base.OnValueChanged(oldValue, newValue); |
||||
|
|
||||
|
Color color = ColorUtilities.ConvertHsvToRgb(360 - newValue, 1, 1); |
||||
|
SelectedColor = color; |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void CreateSpectrum() |
||||
|
{ |
||||
|
_pickerBrush = new LinearGradientBrush(); |
||||
|
_pickerBrush.StartPoint = new Point(0.5, 0); |
||||
|
_pickerBrush.EndPoint = new Point(0.5, 1); |
||||
|
_pickerBrush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; |
||||
|
|
||||
|
List<Color> colorsList = ColorUtilities.GenerateHsvSpectrum(); |
||||
|
|
||||
|
double stopIncrement = (double)1 / colorsList.Count; |
||||
|
|
||||
|
int i; |
||||
|
for (i = 0; i < colorsList.Count; i++) |
||||
|
{ |
||||
|
_pickerBrush.GradientStops.Add(new GradientStop(colorsList[i], i * stopIncrement)); |
||||
|
} |
||||
|
|
||||
|
_pickerBrush.GradientStops[i - 1].Offset = 1.0; |
||||
|
_spectrumDisplay.Fill = _pickerBrush; |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,346 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"> |
||||
|
|
||||
|
<coreConverters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" /> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="ColorPickerDarkBorderBrush" 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="ColorCanvasBackgroundBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFffffff"/> |
||||
|
<GradientStop Offset="1" Color="#FFE8EBED"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<DrawingBrush x:Key="CheckerBrush" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile"> |
||||
|
<DrawingBrush.Drawing> |
||||
|
<DrawingGroup> |
||||
|
<GeometryDrawing Brush="White"> |
||||
|
<GeometryDrawing.Geometry> |
||||
|
<RectangleGeometry Rect="0,0 100,100" /> |
||||
|
</GeometryDrawing.Geometry> |
||||
|
</GeometryDrawing> |
||||
|
<GeometryDrawing Brush="LightGray"> |
||||
|
<GeometryDrawing.Geometry> |
||||
|
<GeometryGroup> |
||||
|
<RectangleGeometry Rect="0,0 50,50" /> |
||||
|
<RectangleGeometry Rect="50,50 50,50" /> |
||||
|
</GeometryGroup> |
||||
|
</GeometryDrawing.Geometry> |
||||
|
</GeometryDrawing> |
||||
|
</DrawingGroup> |
||||
|
</DrawingBrush.Drawing> |
||||
|
</DrawingBrush> |
||||
|
|
||||
|
<SolidColorBrush x:Key="HorizontalSliderTrackNormalBackground" Color="#FFE7EAEA"/> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="HorizontalSliderTrackNormalBorder" EndPoint="0,1" StartPoint="0,0"> |
||||
|
<GradientStop Color="#FFAEB1AF" Offset="0.1"/> |
||||
|
<GradientStop Color="White" Offset=".9"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="ThumbStroke" 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="ThumbFill" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFfefefe"/> |
||||
|
<GradientStop Offset="0.5" Color="#FFeff1f2"/> |
||||
|
<GradientStop Offset="1" Color="#FFd0d6db"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<SolidColorBrush x:Key="ThumbMouseOver" Color="#FFE5F2F6"/> |
||||
|
|
||||
|
<Style x:Key="ColorCanvasTextBoxStyle" TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}"> |
||||
|
<Setter Property="Background" Value="Transparent" /> |
||||
|
<Style.Triggers> |
||||
|
<Trigger Property="IsFocused" Value="False"> |
||||
|
<Setter Property="BorderBrush" Value="Transparent" /> |
||||
|
</Trigger> |
||||
|
</Style.Triggers> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="SliderRepeatButtonStyle" |
||||
|
TargetType="{x:Type RepeatButton}"> |
||||
|
<Setter Property="OverridesDefaultStyle" Value="true"/> |
||||
|
<Setter Property="IsTabStop" Value="false"/> |
||||
|
<Setter Property="Focusable" Value="false"/> |
||||
|
<Setter Property="Background" Value="Transparent"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type RepeatButton}"> |
||||
|
<Border Background="{TemplateBinding Background}"/> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="CustomThumbForSlider" TargetType="{x:Type Thumb}"> |
||||
|
<Setter Property="OverridesDefaultStyle" Value="True"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type Thumb}"> |
||||
|
<Rectangle x:Name="_thumb" Fill="{StaticResource ThumbFill}" Stroke="{StaticResource ThumbStroke}" Height="14" Width="8" RadiusX="1" RadiusY="1"/> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||
|
<Setter TargetName="_thumb" Property="Rectangle.Fill" Value="{StaticResource ThumbMouseOver}" /> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="VerticalSlideThumbStyle" TargetType="{x:Type Thumb}"> |
||||
|
<Setter Property="Focusable" Value="false"/> |
||||
|
<Setter Property="OverridesDefaultStyle" Value="true"/> |
||||
|
<Setter Property="Height" Value="12"/> |
||||
|
<Setter Property="Width" Value="11"/> |
||||
|
<Setter Property="Foreground" Value="Gray"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type Thumb}"> |
||||
|
<Canvas SnapsToDevicePixels="true"> |
||||
|
<Path x:Name="LeftArrow" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF000000" Data="F1 M 276.761,316L 262.619,307.835L 262.619,324.165L 276.761,316 Z " RenderTransformOrigin="0.5,0.5" Width="6" Height="8" > |
||||
|
<Path.RenderTransform> |
||||
|
<TransformGroup> |
||||
|
<ScaleTransform/> |
||||
|
<SkewTransform/> |
||||
|
<RotateTransform /> |
||||
|
<TranslateTransform Y="6" X="-3"/> |
||||
|
</TransformGroup> |
||||
|
</Path.RenderTransform> |
||||
|
</Path> |
||||
|
<Path x:Name="RightArrow" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF000000" Data="F1 M 276.761,316L 262.619,307.835L 262.619,324.165L 276.761,316 Z " RenderTransformOrigin="0.5,0.5" Width="6" Height="8" > |
||||
|
<Path.RenderTransform> |
||||
|
<TransformGroup> |
||||
|
<ScaleTransform/> |
||||
|
<SkewTransform/> |
||||
|
<RotateTransform Angle="-180"/> |
||||
|
<TranslateTransform Y="6" X="8"/> |
||||
|
</TransformGroup> |
||||
|
</Path.RenderTransform> |
||||
|
</Path> |
||||
|
</Canvas> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="ColorCanvasSliderStyle" TargetType="{x:Type Slider}"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type Slider}"> |
||||
|
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> |
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
<TickBar x:Name="TopTick" Fill="{TemplateBinding Foreground}" Height="4" Placement="Top" Grid.Row="0" Visibility="Collapsed"/> |
||||
|
<TickBar x:Name="BottomTick" Fill="{TemplateBinding Foreground}" Height="4" Placement="Bottom" Grid.Row="2" Visibility="Collapsed"/> |
||||
|
<Border x:Name="TrackBackground" BorderBrush="{StaticResource HorizontalSliderTrackNormalBorder}" BorderThickness="1" Background="{StaticResource HorizontalSliderTrackNormalBackground}" CornerRadius="1" Height="4.0" Margin="5,0" Grid.Row="1" VerticalAlignment="center"> |
||||
|
<Canvas Margin="-6,-1"> |
||||
|
<Rectangle x:Name="PART_SelectionRange" Fill="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" Height="4.0" Stroke="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}" StrokeThickness="1.0" Visibility="Hidden"/> |
||||
|
</Canvas> |
||||
|
</Border> |
||||
|
<Track x:Name="PART_Track" Grid.Row="1"> |
||||
|
<Track.DecreaseRepeatButton> |
||||
|
<RepeatButton Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource SliderRepeatButtonStyle}"/> |
||||
|
</Track.DecreaseRepeatButton> |
||||
|
<Track.IncreaseRepeatButton> |
||||
|
<RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource SliderRepeatButtonStyle}"/> |
||||
|
</Track.IncreaseRepeatButton> |
||||
|
<Track.Thumb> |
||||
|
<Thumb x:Name="Thumb" Style="{StaticResource CustomThumbForSlider}"/> |
||||
|
</Track.Thumb> |
||||
|
</Track> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:ColorCanvas}"> |
||||
|
<Setter Property="Background" Value="{StaticResource ColorCanvasBackgroundBrush}" /> |
||||
|
<Setter Property="BorderBrush" Value="{StaticResource ColorPickerDarkBorderBrush}" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:ColorCanvas}"> |
||||
|
<Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Padding="3"> |
||||
|
<Grid Margin="2"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions > |
||||
|
<ColumnDefinition Width="200"></ColumnDefinition> |
||||
|
<ColumnDefinition Width="Auto"></ColumnDefinition> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<Border BorderThickness="1" BorderBrush="DarkGray" ClipToBounds="True" Background="{StaticResource CheckerBrush}"> |
||||
|
<Canvas x:Name="PART_ColorShadingCanvas" Width="200" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top"> |
||||
|
<Rectangle x:Name="ColorShadingRectangle" Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}" Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}" |
||||
|
Fill="{Binding SelectedColor, ElementName=PART_SpectrumSlider, Converter={StaticResource ColorToSolidColorBrushConverter}}" /> |
||||
|
<Rectangle x:Name="WhiteGradient" Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}" Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}" > |
||||
|
<Rectangle.Fill> |
||||
|
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> |
||||
|
<GradientStop Offset="0" Color="#ffffffff"/> |
||||
|
<GradientStop Offset="1" Color="Transparent"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Rectangle.Fill> |
||||
|
</Rectangle> |
||||
|
<Rectangle x:Name="BlackGradient" Width="{Binding ElementName=PART_ColorShadingCanvas,Path=Width}" Height="{Binding ElementName=PART_ColorShadingCanvas,Path=Height}" > |
||||
|
<Rectangle.Fill> |
||||
|
<LinearGradientBrush StartPoint="0,1" EndPoint="0, 0"> |
||||
|
<GradientStop Offset="0" Color="#ff000000"/> |
||||
|
<GradientStop Offset="1" Color="#00000000"/> |
||||
|
</LinearGradientBrush> |
||||
|
</Rectangle.Fill> |
||||
|
</Rectangle> |
||||
|
<Canvas x:Name="PART_ColorShadeSelector" Width="10" Height="10" IsHitTestVisible="False"> |
||||
|
<Ellipse Width="10" Height="10" StrokeThickness="3" Stroke="#FFFFFFFF" IsHitTestVisible="False" /> |
||||
|
<Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="#FF000000" IsHitTestVisible="False" /> |
||||
|
</Canvas> |
||||
|
</Canvas> |
||||
|
</Border> |
||||
|
|
||||
|
<Border Grid.Row="1" Margin="0,5,0,0"> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*" /> |
||||
|
<ColumnDefinition Width="*" /> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Border Background="{StaticResource CheckerBrush}" Height="22" Margin="2,0,2,0" BorderThickness="1" BorderBrush="#FFC9CACA"> |
||||
|
<Rectangle x:Name="SelectedColor" Fill="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorToSolidColorBrushConverter}}" /> |
||||
|
</Border> |
||||
|
<TextBox Grid.Column="1" Text="{Binding HexadecimalString, RelativeSource={RelativeSource TemplatedParent}}" Margin="2,0,2,0" VerticalAlignment="Center" Style="{StaticResource ColorCanvasTextBoxStyle}" /> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
|
||||
|
<Border Grid.Column="1" Grid.RowSpan="2" Margin="4,-8,0,0" ClipToBounds="False"> |
||||
|
<local:ColorSpectrumSlider x:Name="PART_SpectrumSlider" VerticalAlignment="Stretch" /> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
|
||||
|
<Border MinWidth="180" Grid.Row="1" BorderThickness="1" ClipToBounds="True" Margin="0,10,0,0"> |
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
<RowDefinition Height="Auto"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
<ColumnDefinition Width="*"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<TextBlock Grid.Row="0" Grid.Column="0" Text="R" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<Slider x:Name="PART_RSlider" Maximum="255" TickFrequency="1" Grid.Row="0" Grid.Column="1" Margin="4,6,4,6" |
||||
|
Style="{StaticResource ColorCanvasSliderStyle}" |
||||
|
Value="{Binding R, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding Value, ElementName=PART_RSlider}" |
||||
|
VerticalAlignment="Center" |
||||
|
Style="{StaticResource ColorCanvasTextBoxStyle}"/> |
||||
|
|
||||
|
<TextBlock Grid.Row="1" Grid.Column="0" Text="G" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<Slider x:Name="PART_GSlider" Maximum="255" TickFrequency="1" Grid.Row="1" Grid.Column="1" Margin="4,6,4,6" |
||||
|
Style="{StaticResource ColorCanvasSliderStyle}" |
||||
|
Value="{Binding G, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Value, ElementName=PART_GSlider}" |
||||
|
VerticalAlignment="Center" Style="{StaticResource ColorCanvasTextBoxStyle}"/> |
||||
|
|
||||
|
<TextBlock Grid.Row="2" Grid.Column="0" Text="B" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<Slider x:Name="PART_BSlider" Maximum="255" TickFrequency="1" Grid.Row="2" Grid.Column="1" Margin="4,6,4,6" |
||||
|
Style="{StaticResource ColorCanvasSliderStyle}" |
||||
|
Value="{Binding B, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<TextBox Grid.Row="2" Grid.Column="3" Text="{Binding Value, ElementName=PART_BSlider}" |
||||
|
VerticalAlignment="Center" Style="{StaticResource ColorCanvasTextBoxStyle}"/> |
||||
|
|
||||
|
<TextBlock Grid.Row="3" Grid.Column="0" Text="A" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<Slider x:Name="PART_OpacitySlider" Grid.Row="3" Grid.Column="1" Maximum="255" Margin="4,6,4,6" |
||||
|
Style="{StaticResource ColorCanvasSliderStyle}" |
||||
|
Value="{Binding Path=A, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
VerticalAlignment="Center"/> |
||||
|
<TextBox Grid.Row="3" Grid.Column="3" Text="{Binding Value, ElementName=PART_OpacitySlider}" |
||||
|
VerticalAlignment="Center" Style="{StaticResource ColorCanvasTextBoxStyle}"/> |
||||
|
|
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:ColorSpectrumSlider}"> |
||||
|
<Setter Property="Orientation" Value="Vertical"/> |
||||
|
<Setter Property="Background" Value="Transparent"/> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> |
||||
|
<Setter Property="Minimum" Value="1"/> |
||||
|
<Setter Property="Maximum" Value="360"/> |
||||
|
<Setter Property="TickFrequency" Value="0.001" /> |
||||
|
<Setter Property="IsSnapToTickEnabled" Value="True" /> |
||||
|
<Setter Property="IsDirectionReversed" Value="False" /> |
||||
|
<Setter Property="IsMoveToPointEnabled" Value="True" /> |
||||
|
<Setter Property="Value" Value="0" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:ColorSpectrumSlider}"> |
||||
|
<Grid> |
||||
|
<Border x:Name="PART_TrackBackground" BorderBrush="DarkGray" BorderThickness="1" Width="15" Margin="0,8,0,0" > |
||||
|
<Rectangle x:Name="PART_SpectrumDisplay" Stretch="Fill" VerticalAlignment="Stretch" /> |
||||
|
</Border> |
||||
|
|
||||
|
<Track Name="PART_Track"> |
||||
|
<Track.DecreaseRepeatButton> |
||||
|
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}" Command="Slider.DecreaseLarge"/> |
||||
|
</Track.DecreaseRepeatButton> |
||||
|
<Track.IncreaseRepeatButton> |
||||
|
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}" Command="Slider.IncreaseLarge"/> |
||||
|
</Track.IncreaseRepeatButton> |
||||
|
<Track.Thumb> |
||||
|
<Thumb Style="{StaticResource VerticalSlideThumbStyle}" /> |
||||
|
</Track.Thumb> |
||||
|
</Track> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class ColorItem |
||||
|
{ |
||||
|
public Color Color { get; set; } |
||||
|
public string Name { get; set; } |
||||
|
|
||||
|
public ColorItem(Color color, string name) |
||||
|
{ |
||||
|
Color = color; |
||||
|
Name = name; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,317 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Windows.Input; |
||||
|
using Microsoft.Windows.Controls.Core.Utilities; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class ColorPicker : Control |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private Popup _colorPickerCanvasPopup; |
||||
|
private ListBox _availableColors; |
||||
|
private ListBox _standardColors; |
||||
|
private ListBox _recentColors; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region AvailableColors
|
||||
|
|
||||
|
public static readonly DependencyProperty AvailableColorsProperty = DependencyProperty.Register("AvailableColors", typeof(ObservableCollection<ColorItem>), typeof(ColorPicker), new UIPropertyMetadata(CreateAvailableColors())); |
||||
|
public ObservableCollection<ColorItem> AvailableColors |
||||
|
{ |
||||
|
get { return (ObservableCollection<ColorItem>)GetValue(AvailableColorsProperty); } |
||||
|
set { SetValue(AvailableColorsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //AvailableColors
|
||||
|
|
||||
|
#region ButtonStyle
|
||||
|
|
||||
|
public static readonly DependencyProperty ButtonStyleProperty = DependencyProperty.Register("ButtonStyle", typeof(Style), typeof(ColorPicker)); |
||||
|
public Style ButtonStyle |
||||
|
{ |
||||
|
get { return (Style)GetValue(ButtonStyleProperty); } |
||||
|
set { SetValue(ButtonStyleProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ButtonStyle
|
||||
|
|
||||
|
#region DisplayColorAndName
|
||||
|
|
||||
|
public static readonly DependencyProperty DisplayColorAndNameProperty = DependencyProperty.Register("DisplayColorAndName", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false)); |
||||
|
public bool DisplayColorAndName |
||||
|
{ |
||||
|
get { return (bool)GetValue(DisplayColorAndNameProperty); } |
||||
|
set { SetValue(DisplayColorAndNameProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //DisplayColorAndName
|
||||
|
|
||||
|
#region IsOpen
|
||||
|
|
||||
|
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false)); |
||||
|
public bool IsOpen |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsOpenProperty); } |
||||
|
set { SetValue(IsOpenProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //IsOpen
|
||||
|
|
||||
|
#region RecentColors
|
||||
|
|
||||
|
public static readonly DependencyProperty RecentColorsProperty = DependencyProperty.Register("RecentColors", typeof(ObservableCollection<ColorItem>), typeof(ColorPicker), new UIPropertyMetadata(null)); |
||||
|
public ObservableCollection<ColorItem> RecentColors |
||||
|
{ |
||||
|
get { return (ObservableCollection<ColorItem>)GetValue(RecentColorsProperty); } |
||||
|
set { SetValue(RecentColorsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //RecentColors
|
||||
|
|
||||
|
#region SelectedColor
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorPicker), new FrameworkPropertyMetadata(Colors.Black, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnSelectedColorPropertyChanged))); |
||||
|
public Color SelectedColor |
||||
|
{ |
||||
|
get { return (Color)GetValue(SelectedColorProperty); } |
||||
|
set { SetValue(SelectedColorProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnSelectedColorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ColorPicker colorPicker = (ColorPicker)d; |
||||
|
if (colorPicker != null) |
||||
|
colorPicker.OnSelectedColorChanged((Color)e.OldValue, (Color)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
private void OnSelectedColorChanged(Color oldValue, Color newValue) |
||||
|
{ |
||||
|
SelectedColorText = newValue.GetColorName(); |
||||
|
|
||||
|
RoutedPropertyChangedEventArgs<Color> args = new RoutedPropertyChangedEventArgs<Color>(oldValue, newValue); |
||||
|
args.RoutedEvent = ColorPicker.SelectedColorChangedEvent; |
||||
|
RaiseEvent(args); |
||||
|
} |
||||
|
|
||||
|
#endregion //SelectedColor
|
||||
|
|
||||
|
#region SelectedColorText
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectedColorTextProperty = DependencyProperty.Register("SelectedColorText", typeof(string), typeof(ColorPicker), new UIPropertyMetadata("Black")); |
||||
|
public string SelectedColorText |
||||
|
{ |
||||
|
get { return (string)GetValue(SelectedColorTextProperty); } |
||||
|
protected set { SetValue(SelectedColorTextProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //SelectedColorText
|
||||
|
|
||||
|
#region ShowAdvancedButton
|
||||
|
|
||||
|
public static readonly DependencyProperty ShowAdvancedButtonProperty = DependencyProperty.Register("ShowAdvancedButton", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); |
||||
|
public bool ShowAdvancedButton |
||||
|
{ |
||||
|
get { return (bool)GetValue(ShowAdvancedButtonProperty); } |
||||
|
set { SetValue(ShowAdvancedButtonProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ShowAdvancedButton
|
||||
|
|
||||
|
#region ShowAvailableColors
|
||||
|
|
||||
|
public static readonly DependencyProperty ShowAvailableColorsProperty = DependencyProperty.Register("ShowAvailableColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); |
||||
|
public bool ShowAvailableColors |
||||
|
{ |
||||
|
get { return (bool)GetValue(ShowAvailableColorsProperty); } |
||||
|
set { SetValue(ShowAvailableColorsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ShowAvailableColors
|
||||
|
|
||||
|
#region ShowRecentColors
|
||||
|
|
||||
|
public static readonly DependencyProperty ShowRecentColorsProperty = DependencyProperty.Register("ShowRecentColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(false)); |
||||
|
public bool ShowRecentColors |
||||
|
{ |
||||
|
get { return (bool)GetValue(ShowRecentColorsProperty); } |
||||
|
set { SetValue(ShowRecentColorsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //DisplayRecentColors
|
||||
|
|
||||
|
#region ShowStandardColors
|
||||
|
|
||||
|
public static readonly DependencyProperty ShowStandardColorsProperty = DependencyProperty.Register("ShowStandardColors", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); |
||||
|
public bool ShowStandardColors |
||||
|
{ |
||||
|
get { return (bool)GetValue(ShowStandardColorsProperty); } |
||||
|
set { SetValue(ShowStandardColorsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //DisplayStandardColors
|
||||
|
|
||||
|
#region StandardColors
|
||||
|
|
||||
|
public static readonly DependencyProperty StandardColorsProperty = DependencyProperty.Register("StandardColors", typeof(ObservableCollection<ColorItem>), typeof(ColorPicker), new UIPropertyMetadata(CreateStandardColors())); |
||||
|
public ObservableCollection<ColorItem> StandardColors |
||||
|
{ |
||||
|
get { return (ObservableCollection<ColorItem>)GetValue(StandardColorsProperty); } |
||||
|
set { SetValue(StandardColorsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //StandardColors
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static ColorPicker() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); |
||||
|
} |
||||
|
|
||||
|
public ColorPicker() |
||||
|
{ |
||||
|
RecentColors = new ObservableCollection<ColorItem>(); |
||||
|
Keyboard.AddKeyDownHandler(this, OnKeyDown); |
||||
|
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_colorPickerCanvasPopup = (Popup)GetTemplateChild("PART_ColorPickerPalettePopup"); |
||||
|
//_colorPickerCanvasPopup.Opened += ColorPickerCanvasPopup_Opened;
|
||||
|
|
||||
|
_availableColors = (ListBox)GetTemplateChild("PART_AvailableColors"); |
||||
|
_availableColors.SelectionChanged += Color_SelectionChanged; |
||||
|
|
||||
|
_standardColors = (ListBox)GetTemplateChild("PART_StandardColors"); |
||||
|
_standardColors.SelectionChanged += Color_SelectionChanged; |
||||
|
|
||||
|
_recentColors = (ListBox)GetTemplateChild("PART_RecentColors"); |
||||
|
_recentColors.SelectionChanged += Color_SelectionChanged; |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void ColorPickerCanvasPopup_Opened(object sender, EventArgs e) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
private void OnKeyDown(object sender, KeyEventArgs e) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Escape: |
||||
|
case Key.Tab: |
||||
|
{ |
||||
|
CloseColorPicker(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
CloseColorPicker(); |
||||
|
} |
||||
|
|
||||
|
private void Color_SelectionChanged(object sender, SelectionChangedEventArgs e) |
||||
|
{ |
||||
|
ListBox lb = (ListBox)sender; |
||||
|
|
||||
|
if (e.AddedItems.Count > 0) |
||||
|
{ |
||||
|
var colorItem = (ColorItem)e.AddedItems[0]; |
||||
|
SelectedColor = colorItem.Color; |
||||
|
UpdateRecentColors(colorItem); |
||||
|
CloseColorPicker(); |
||||
|
lb.SelectedIndex = -1; //for now I don't care about keeping track of the selected color
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPicker)); |
||||
|
public event RoutedPropertyChangedEventHandler<Color> SelectedColorChanged |
||||
|
{ |
||||
|
add { AddHandler(SelectedColorChangedEvent, value); } |
||||
|
remove { RemoveHandler(SelectedColorChangedEvent, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void CloseColorPicker() |
||||
|
{ |
||||
|
if (IsOpen) |
||||
|
IsOpen = false; |
||||
|
ReleaseMouseCapture(); |
||||
|
} |
||||
|
|
||||
|
private void UpdateRecentColors(ColorItem colorItem) |
||||
|
{ |
||||
|
if (!RecentColors.Contains(colorItem)) |
||||
|
RecentColors.Add(colorItem); |
||||
|
|
||||
|
if (RecentColors.Count > 10) //don't allow more than ten, maybe make a property that can be set by the user.
|
||||
|
RecentColors.RemoveAt(0); |
||||
|
} |
||||
|
|
||||
|
private static ObservableCollection<ColorItem> CreateStandardColors() |
||||
|
{ |
||||
|
ObservableCollection<ColorItem> _standardColors = new ObservableCollection<ColorItem>(); |
||||
|
_standardColors.Add(new ColorItem(Colors.Transparent, "Transparent")); |
||||
|
_standardColors.Add(new ColorItem(Colors.White, "White")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Gray, "Gray")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Black, "Black")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Red, "Red")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Green, "Green")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Blue, "Blue")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Yellow, "Yellow")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Orange, "Orange")); |
||||
|
_standardColors.Add(new ColorItem(Colors.Purple, "Purple")); |
||||
|
return _standardColors; |
||||
|
} |
||||
|
|
||||
|
private static ObservableCollection<ColorItem> CreateAvailableColors() |
||||
|
{ |
||||
|
ObservableCollection<ColorItem> _standardColors = new ObservableCollection<ColorItem>(); |
||||
|
|
||||
|
foreach (var item in ColorUtilities.KnownColors) |
||||
|
{ |
||||
|
if (!String.Equals(item.Key, "Transparent")) |
||||
|
{ |
||||
|
var colorItem = new ColorItem(item.Value, item.Key); |
||||
|
if (!_standardColors.Contains(colorItem)) |
||||
|
_standardColors.Add(colorItem); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return _standardColors; |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,278 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters" |
||||
|
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes"> |
||||
|
|
||||
|
<SolidColorBrush x:Key="ButtonHover" Color="#C2E0FF"/> |
||||
|
<SolidColorBrush x:Key="ButtonHoverBorder" Color="#3399FF"/> |
||||
|
<SolidColorBrush x:Key="ButtonChecked" Color="#E6F0FA"/> |
||||
|
<SolidColorBrush x:Key="ButtonPressed" Color="#99CCFF"/> |
||||
|
<SolidColorBrush x:Key="ButtonPressedBorder" Color="#3399FF"/> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- ColorPicker --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> |
||||
|
<coreConverters:InverseBoolConverter x:Key="InverseBoolConverter" /> |
||||
|
<coreConverters:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" /> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="ColorPickerDarkBorderBrush" 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> |
||||
|
|
||||
|
<DrawingBrush x:Key="CheckerBrush" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile"> |
||||
|
<DrawingBrush.Drawing> |
||||
|
<DrawingGroup> |
||||
|
<GeometryDrawing Brush="White"> |
||||
|
<GeometryDrawing.Geometry> |
||||
|
<RectangleGeometry Rect="0,0 100,100" /> |
||||
|
</GeometryDrawing.Geometry> |
||||
|
</GeometryDrawing> |
||||
|
<GeometryDrawing Brush="LightGray"> |
||||
|
<GeometryDrawing.Geometry> |
||||
|
<GeometryGroup> |
||||
|
<RectangleGeometry Rect="0,0 50,50" /> |
||||
|
<RectangleGeometry Rect="50,50 50,50" /> |
||||
|
</GeometryGroup> |
||||
|
</GeometryDrawing.Geometry> |
||||
|
</GeometryDrawing> |
||||
|
</DrawingGroup> |
||||
|
</DrawingBrush.Drawing> |
||||
|
</DrawingBrush> |
||||
|
|
||||
|
<Style x:Key="ColorPaletteLisBoxStyle" TargetType="{x:Type ListBoxItem}"> |
||||
|
<Setter Property="ToolTip" Value="{Binding Name}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type ListBoxItem}"> |
||||
|
<Grid ToolTip="{Binding Name}"> |
||||
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> |
||||
|
<Border BorderThickness="1" Background="Transparent" BorderBrush="Transparent" x:Name="_outerBorder" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> |
||||
|
<Border Background="Transparent" BorderThickness="1" BorderBrush="Transparent" x:Name="_innerBorder" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="IsMouseOver" Value="True"> |
||||
|
<Setter TargetName="_outerBorder" Property="BorderBrush" Value="#FFFF0000" /> |
||||
|
<Setter TargetName="_innerBorder" Property="BorderBrush" Value="#FFFFFF00" /> |
||||
|
</Trigger> |
||||
|
<Trigger Property="IsSelected" Value="True"> |
||||
|
<Setter TargetName="_outerBorder" Property="BorderBrush" Value="#FFFF0000" /> |
||||
|
<Setter TargetName="_innerBorder" Property="BorderBrush" Value="#FFFFFF00" /> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<DataTemplate x:Key="ColorItemTemplate"> |
||||
|
<Grid> |
||||
|
<Border BorderBrush="#FFC9CACA" BorderThickness="1" Margin="2,2,2,2" > |
||||
|
<Rectangle Width="14" Height="14"> |
||||
|
<Rectangle.Style> |
||||
|
<Style TargetType="Rectangle"> |
||||
|
<Setter Property="Fill" Value="{Binding Color, Converter={StaticResource ColorToSolidColorBrushConverter}}" /> |
||||
|
<Style.Triggers> |
||||
|
<DataTrigger Binding="{Binding Name}" Value="Transparent"> |
||||
|
<Setter Property="Fill" Value="{StaticResource CheckerBrush}" /> |
||||
|
</DataTrigger> |
||||
|
</Style.Triggers> |
||||
|
</Style> |
||||
|
</Rectangle.Style> |
||||
|
</Rectangle> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<Style x:Key="ColorPickerToggleButtonStyle" TargetType="ToggleButton"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="ToggleButton"> |
||||
|
<Grid SnapsToDevicePixels="True"> |
||||
|
<chrome:ButtonChrome x:Name="ToggleButtonChrome" |
||||
|
RenderChecked="{Binding IsOpen, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ColorPicker}}" |
||||
|
RenderEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ColorPicker}}" |
||||
|
RenderMouseOver="{TemplateBinding IsMouseOver}" |
||||
|
RenderPressed="{TemplateBinding IsPressed}" /> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> |
||||
|
|
||||
|
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Grid.Column="1" Margin="5"> |
||||
|
<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> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style x:Key="ColorDisplayStyle" TargetType="Border"> |
||||
|
<Setter Property="Background" Value="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorToSolidColorBrushConverter}}" /> |
||||
|
<Style.Triggers> |
||||
|
<DataTrigger Binding="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}}" Value="Transparent"> |
||||
|
<Setter Property="Background" Value="{StaticResource CheckerBrush}" /> |
||||
|
</DataTrigger> |
||||
|
</Style.Triggers> |
||||
|
</Style> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:ColorPicker}"> |
||||
|
<Setter Property="BorderBrush" Value="{StaticResource ColorPickerDarkBorderBrush}" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="ButtonStyle" Value="{StaticResource ColorPickerToggleButtonStyle}" /> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:ColorPicker}"> |
||||
|
<Grid> |
||||
|
<ToggleButton x:Name="PART_ColorPickerToggleButton" IsTabStop="True" MinHeight="22" IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" |
||||
|
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" |
||||
|
Style="{TemplateBinding ButtonStyle}"> |
||||
|
<Grid Margin="2,2,0,2"> |
||||
|
<Border x:Name="ColorOnly" Style="{StaticResource ColorDisplayStyle}" /> |
||||
|
|
||||
|
<Border x:Name="ColorAndName" Background="White" Visibility="Hidden"> |
||||
|
<StackPanel Orientation="Horizontal"> |
||||
|
<Border HorizontalAlignment="Left" Width="20" Margin="2,1,4,1" Style="{StaticResource ColorDisplayStyle}" BorderThickness="1" BorderBrush="#FFC9CACA" /> |
||||
|
<TextBlock Text="{Binding SelectedColorText, RelativeSource={RelativeSource TemplatedParent}}" VerticalAlignment="Center" /> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</ToggleButton> |
||||
|
|
||||
|
<Popup x:Name="PART_ColorPickerPalettePopup" VerticalAlignment="Bottom" IsOpen="{Binding ElementName=PART_ColorPickerToggleButton, Path=IsChecked}" StaysOpen="False" AllowsTransparency="True" Focusable="False" HorizontalOffset="1" VerticalOffset="1" > |
||||
|
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource ColorPickerDarkBorderBrush}" Padding="3"> |
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<Grid x:Name="_gridStandardColorsHost" Margin="4"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<!-- Available Colors --> |
||||
|
<Grid Grid.Row="1" Visibility="{TemplateBinding ShowAvailableColors, Converter={StaticResource BooleanToVisibilityConverter}}"> |
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<TextBlock Text="Available Colors" Background="AliceBlue" Padding="2" Margin="0,0,0,1" /> |
||||
|
<ListBox x:Name="PART_AvailableColors" Grid.Row="1" Background="Transparent" BorderThickness="0" SelectionMode="Single" |
||||
|
ItemsSource="{Binding AvailableColors, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
ItemTemplate="{StaticResource ColorItemTemplate}" |
||||
|
ItemContainerStyle="{StaticResource ColorPaletteLisBoxStyle}" |
||||
|
Style="{x:Null}"> |
||||
|
<ListBox.ItemsPanel> |
||||
|
<ItemsPanelTemplate> |
||||
|
<WrapPanel Width="200" /> |
||||
|
</ItemsPanelTemplate> |
||||
|
</ListBox.ItemsPanel> |
||||
|
</ListBox> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
|
||||
|
<!-- Standard Colors--> |
||||
|
<Grid Grid.Row="2" Visibility="{TemplateBinding ShowStandardColors, Converter={StaticResource BooleanToVisibilityConverter}}"> |
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<TextBlock Text="Standard Colors" Background="AliceBlue" Padding="2" Margin="0,1,0,1"/> |
||||
|
<ListBox x:Name="PART_StandardColors" Grid.Row="1" SelectionMode="Single" Background="Transparent" BorderThickness="0" |
||||
|
ItemsSource="{Binding StandardColors, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
ItemTemplate="{StaticResource ColorItemTemplate}" |
||||
|
ItemContainerStyle="{StaticResource ColorPaletteLisBoxStyle}" |
||||
|
Style="{x:Null}"> |
||||
|
<ListBox.ItemsPanel> |
||||
|
<ItemsPanelTemplate> |
||||
|
<WrapPanel Width="200" /> |
||||
|
</ItemsPanelTemplate> |
||||
|
</ListBox.ItemsPanel> |
||||
|
</ListBox> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
|
||||
|
<!-- Recent Colors--> |
||||
|
<Grid Grid.Row="3" Margin="0,1,0,1" Visibility="{TemplateBinding ShowRecentColors, Converter={StaticResource BooleanToVisibilityConverter}}"> |
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<TextBlock Text="Recent Colors" Background="AliceBlue" Padding="2" Margin="0,1,0,1"/> |
||||
|
<ListBox x:Name="PART_RecentColors" Grid.Row="1" SelectionMode="Single" Background="Transparent" BorderThickness="0" |
||||
|
ItemsSource="{Binding RecentColors, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
ItemTemplate="{StaticResource ColorItemTemplate}" |
||||
|
ItemContainerStyle="{StaticResource ColorPaletteLisBoxStyle}" |
||||
|
Style="{x:Null}"> |
||||
|
<ListBox.ItemsPanel> |
||||
|
<ItemsPanelTemplate> |
||||
|
<WrapPanel Width="200" /> |
||||
|
</ItemsPanelTemplate> |
||||
|
</ListBox.ItemsPanel> |
||||
|
</ListBox> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
|
||||
|
<!-- ColorCanvas --> |
||||
|
<Grid x:Name="_colorCanvasHost" Visibility="Collapsed"> |
||||
|
<local:ColorCanvas x:Name="PART_ColorCanvas" Background="Transparent" BorderThickness="0" |
||||
|
SelectedColor="{Binding SelectedColor, RelativeSource={RelativeSource TemplatedParent}}" /> |
||||
|
</Grid> |
||||
|
|
||||
|
<Separator Grid.Row="1" HorizontalAlignment="Stretch" Margin="5,0,5,0" /> |
||||
|
|
||||
|
<!-- More Colors Button --> |
||||
|
<ToggleButton x:Name="_colorMode" Grid.Row="2" Content="Advanced" Margin="5" Visibility="{TemplateBinding ShowAdvancedButton, Converter={StaticResource BooleanToVisibilityConverter}}" /> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Popup> |
||||
|
</Grid> |
||||
|
<ControlTemplate.Triggers> |
||||
|
<Trigger Property="DisplayColorAndName" Value="True"> |
||||
|
<Setter TargetName="ColorOnly" Property="Visibility" Value="Collapsed" /> |
||||
|
<Setter TargetName="ColorAndName" Property="Visibility" Value="Visible" /> |
||||
|
</Trigger> |
||||
|
<Trigger SourceName="_colorMode" Property="IsChecked" Value="True"> |
||||
|
<Setter TargetName="_colorMode" Property="Content" Value="Standard" /> |
||||
|
<Setter TargetName="_colorCanvasHost" Property="Visibility" Value="Visible" /> |
||||
|
<Setter TargetName="_gridStandardColorsHost" Property="Visibility" Value="Collapsed" /> |
||||
|
</Trigger> |
||||
|
</ControlTemplate.Triggers> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,19 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Converters |
||||
|
{ |
||||
|
public class CalculatorMemoryToVisibilityConverter : IValueConverter |
||||
|
{ |
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
return (decimal)value == decimal.Zero ? Visibility.Hidden : Visibility.Visible; |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Converters |
||||
|
{ |
||||
|
public class ColorToSolidColorBrushConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a Color to a SolidColorBrush.
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">The Color produced by the binding source.</param>
|
||||
|
/// <param name="targetType">The type of the binding target property.</param>
|
||||
|
/// <param name="parameter">The converter parameter to use.</param>
|
||||
|
/// <param name="culture">The culture to use in the converter.</param>
|
||||
|
/// <returns>
|
||||
|
/// A converted SolidColorBrush. If the method returns null, the valid null value is used.
|
||||
|
/// </returns>
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
if (value != null) |
||||
|
return new SolidColorBrush((Color)value); |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a SolidColorBrush to a Color.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>Currently not used in toolkit, but provided for developer use in their own projects</remarks>
|
||||
|
/// <param name="value">The SolidColorBrush that is produced by the binding target.</param>
|
||||
|
/// <param name="targetType">The type to convert to.</param>
|
||||
|
/// <param name="parameter">The converter parameter to use.</param>
|
||||
|
/// <param name="culture">The culture to use in the converter.</param>
|
||||
|
/// <returns>
|
||||
|
/// A converted value. If the method returns null, the valid null value is used.
|
||||
|
/// </returns>
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
if (value != null) |
||||
|
return ((SolidColorBrush)value).Color; |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Converters |
||||
|
{ |
||||
|
public class InverseBoolConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
return !(bool)value; |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Converters |
||||
|
{ |
||||
|
public class SolidColorBrushToColorConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
SolidColorBrush brush = value as SolidColorBrush; |
||||
|
if (brush != null) |
||||
|
return brush.Color; |
||||
|
|
||||
|
return default(Color); |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
if (value != null) |
||||
|
{ |
||||
|
Color color = (Color)value; |
||||
|
return new SolidColorBrush(color); |
||||
|
} |
||||
|
|
||||
|
return default(SolidColorBrush); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Converters |
||||
|
{ |
||||
|
public class TimeFormatToDateTimeFormatConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
TimeFormat timeFormat = (TimeFormat)value; |
||||
|
switch (timeFormat) |
||||
|
{ |
||||
|
case TimeFormat.Custom: |
||||
|
return DateTimeFormat.Custom; |
||||
|
case TimeFormat.ShortTime: |
||||
|
return DateTimeFormat.ShortTime; |
||||
|
case TimeFormat.LongTime: |
||||
|
return DateTimeFormat.LongTime; |
||||
|
default: |
||||
|
return DateTimeFormat.ShortTime; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Primitives |
||||
|
{ |
||||
|
internal struct HsvColor |
||||
|
{ |
||||
|
public double H; |
||||
|
public double S; |
||||
|
public double V; |
||||
|
|
||||
|
public HsvColor(double h, double s, double v) |
||||
|
{ |
||||
|
H = h; |
||||
|
S = s; |
||||
|
V = v; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows; |
||||
|
using System.Globalization; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Primitives |
||||
|
{ |
||||
|
public abstract class InputBase : Control |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
#region CultureInfo
|
||||
|
|
||||
|
public static readonly DependencyProperty CultureInfoProperty = DependencyProperty.Register("CultureInfo", typeof(CultureInfo), typeof(InputBase), new UIPropertyMetadata(CultureInfo.CurrentCulture)); |
||||
|
public CultureInfo CultureInfo |
||||
|
{ |
||||
|
get { return (CultureInfo)GetValue(CultureInfoProperty); } |
||||
|
set { SetValue(CultureInfoProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //CultureInfo
|
||||
|
|
||||
|
#region IsEditable
|
||||
|
|
||||
|
public static readonly DependencyProperty IsEditableProperty = DependencyProperty.Register("IsEditable", typeof(bool), typeof(InputBase), new PropertyMetadata(true)); |
||||
|
public bool IsEditable |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsEditableProperty); } |
||||
|
set { SetValue(IsEditableProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //IsEditable
|
||||
|
|
||||
|
#region Text
|
||||
|
|
||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(InputBase), new UIPropertyMetadata(default(String), OnTextChanged)); |
||||
|
public string Text |
||||
|
{ |
||||
|
get { return (string)GetValue(TextProperty); } |
||||
|
set { SetValue(TextProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
InputBase inputBase = o as InputBase; |
||||
|
if (inputBase != null) |
||||
|
inputBase.OnTextChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnTextChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endregion //Text
|
||||
|
|
||||
|
#region TextAlignment
|
||||
|
|
||||
|
public static readonly DependencyProperty TextAlignmentProperty = DependencyProperty.Register("TextAlignment", typeof(TextAlignment), typeof(InputBase), new UIPropertyMetadata(TextAlignment.Left)); |
||||
|
public TextAlignment TextAlignment |
||||
|
{ |
||||
|
get { return (TextAlignment)GetValue(TextAlignmentProperty); } |
||||
|
set { SetValue(TextAlignmentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#endregion //TextAlignment
|
||||
|
|
||||
|
#region Watermark
|
||||
|
|
||||
|
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(object), typeof(InputBase), new UIPropertyMetadata(null)); |
||||
|
public object Watermark |
||||
|
{ |
||||
|
get { return (object)GetValue(WatermarkProperty); } |
||||
|
set { SetValue(WatermarkProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Watermark
|
||||
|
|
||||
|
#region WatermarkTemplate
|
||||
|
|
||||
|
public static readonly DependencyProperty WatermarkTemplateProperty = DependencyProperty.Register("WatermarkTemplate", typeof(DataTemplate), typeof(InputBase), new UIPropertyMetadata(null)); |
||||
|
public DataTemplate WatermarkTemplate |
||||
|
{ |
||||
|
get { return (DataTemplate)GetValue(WatermarkTemplateProperty); } |
||||
|
set { SetValue(WatermarkTemplateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //WatermarkTemplate
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,316 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Controls; |
||||
|
using Microsoft.Windows.Controls.Primitives; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Primitives |
||||
|
{ |
||||
|
public abstract class UpDownBase<T> : InputBase |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Name constant for Text template part.
|
||||
|
/// </summary>
|
||||
|
internal const string ElementTextName = "TextBox"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Name constant for Spinner template part.
|
||||
|
/// </summary>
|
||||
|
internal const string ElementSpinnerName = "Spinner"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flags if the Text and Value properties are in the process of being sync'd
|
||||
|
/// </summary>
|
||||
|
private bool _isSyncingTextAndValueProperties; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
protected Spinner Spinner { get; private set; } |
||||
|
protected TextBox TextBox { get; private set; } |
||||
|
|
||||
|
#region AllowSpin
|
||||
|
|
||||
|
public static readonly DependencyProperty AllowSpinProperty = DependencyProperty.Register("AllowSpin", typeof(bool), typeof(UpDownBase<T>), new UIPropertyMetadata(true)); |
||||
|
public bool AllowSpin |
||||
|
{ |
||||
|
get { return (bool)GetValue(AllowSpinProperty); } |
||||
|
set { SetValue(AllowSpinProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //AllowSpin
|
||||
|
|
||||
|
#region MouseWheelActiveOnFocus
|
||||
|
|
||||
|
public static readonly DependencyProperty MouseWheelActiveOnFocusProperty = DependencyProperty.Register("MouseWheelActiveOnFocus", typeof(bool), typeof(UpDownBase<T>), new UIPropertyMetadata(true)); |
||||
|
public bool MouseWheelActiveOnFocus |
||||
|
{ |
||||
|
get { return (bool)GetValue(MouseWheelActiveOnFocusProperty); } |
||||
|
set { SetValue(MouseWheelActiveOnFocusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //MouseWheelActiveOnFocus
|
||||
|
|
||||
|
#region ShowButtonSpinner
|
||||
|
|
||||
|
public static readonly DependencyProperty ShowButtonSpinnerProperty = DependencyProperty.Register("ShowButtonSpinner", typeof(bool), typeof(UpDownBase<T>), new UIPropertyMetadata(true)); |
||||
|
public bool ShowButtonSpinner |
||||
|
{ |
||||
|
get { return (bool)GetValue(ShowButtonSpinnerProperty); } |
||||
|
set { SetValue(ShowButtonSpinnerProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ShowButtonSpinner
|
||||
|
|
||||
|
#region Value
|
||||
|
|
||||
|
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(T), typeof(UpDownBase<T>), new FrameworkPropertyMetadata(default(T), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged)); |
||||
|
public T Value |
||||
|
{ |
||||
|
get { return (T)GetValue(ValueProperty); } |
||||
|
set { SetValue(ValueProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
UpDownBase<T> upDownBase = o as UpDownBase<T>; |
||||
|
if (upDownBase != null) |
||||
|
upDownBase.OnValueChanged((T)e.OldValue, (T)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnValueChanged(T oldValue, T newValue) |
||||
|
{ |
||||
|
ValidateValue(newValue); |
||||
|
|
||||
|
SyncTextAndValueProperties(ValueProperty, string.Empty); |
||||
|
|
||||
|
SetValidSpinDirection(); |
||||
|
|
||||
|
RoutedPropertyChangedEventArgs<object> args = new RoutedPropertyChangedEventArgs<object>(oldValue, newValue); |
||||
|
args.RoutedEvent = ValueChangedEvent; |
||||
|
RaiseEvent(args); |
||||
|
} |
||||
|
|
||||
|
#endregion //Value
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
internal UpDownBase() { } |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
protected override void OnAccessKey(AccessKeyEventArgs e) |
||||
|
{ |
||||
|
if (TextBox != null) |
||||
|
TextBox.Focus(); |
||||
|
|
||||
|
base.OnAccessKey(e); |
||||
|
} |
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
TextBox = GetTemplateChild(ElementTextName) as TextBox; |
||||
|
Spinner = GetTemplateChild(ElementSpinnerName) as Spinner; |
||||
|
Spinner.Spin += OnSpinnerSpin; |
||||
|
|
||||
|
SetValidSpinDirection(); |
||||
|
} |
||||
|
|
||||
|
protected override void OnGotFocus(RoutedEventArgs e) |
||||
|
{ |
||||
|
if (TextBox != null) |
||||
|
TextBox.Focus(); |
||||
|
} |
||||
|
|
||||
|
protected override void OnPreviewKeyDown(KeyEventArgs e) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Up: |
||||
|
{ |
||||
|
if (AllowSpin) |
||||
|
DoIncrement(); |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
} |
||||
|
case Key.Down: |
||||
|
{ |
||||
|
if (AllowSpin) |
||||
|
DoDecrement(); |
||||
|
e.Handled = true; |
||||
|
break; |
||||
|
} |
||||
|
case Key.Enter: |
||||
|
{ |
||||
|
if (IsEditable) |
||||
|
{ |
||||
|
var binding = BindingOperations.GetBindingExpression(TextBox, System.Windows.Controls.TextBox.TextProperty); |
||||
|
binding.UpdateSource(); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override void OnMouseWheel(MouseWheelEventArgs e) |
||||
|
{ |
||||
|
base.OnMouseWheel(e); |
||||
|
|
||||
|
if (!e.Handled && AllowSpin && ((TextBox.IsFocused && MouseWheelActiveOnFocus) || !MouseWheelActiveOnFocus)) |
||||
|
{ |
||||
|
if (e.Delta < 0) |
||||
|
{ |
||||
|
DoDecrement(); |
||||
|
} |
||||
|
else if (0 < e.Delta) |
||||
|
{ |
||||
|
DoIncrement(); |
||||
|
} |
||||
|
|
||||
|
e.Handled = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override void OnTextChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
SyncTextAndValueProperties(InputBase.TextProperty, newValue); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
private void OnSpinnerSpin(object sender, SpinEventArgs e) |
||||
|
{ |
||||
|
if (AllowSpin) |
||||
|
OnSpin(e); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
//Due to a bug in Visual Studio, you cannot create event handlers for generic T args in XAML, so I have to use object instead.
|
||||
|
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<object>), typeof(UpDownBase<T>)); |
||||
|
public event RoutedPropertyChangedEventHandler<object> ValueChanged |
||||
|
{ |
||||
|
add { AddHandler(ValueChangedEvent, value); } |
||||
|
remove { RemoveHandler(ValueChangedEvent, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
protected virtual void OnSpin(SpinEventArgs e) |
||||
|
{ |
||||
|
if (e == null) |
||||
|
throw new ArgumentNullException("e"); |
||||
|
|
||||
|
if (e.Direction == SpinDirection.Increase) |
||||
|
DoIncrement(); |
||||
|
else |
||||
|
DoDecrement(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs an increment if conditions allow it.
|
||||
|
/// </summary>
|
||||
|
private void DoDecrement() |
||||
|
{ |
||||
|
if (Spinner == null || (Spinner.ValidSpinDirection & ValidSpinDirections.Decrease) == ValidSpinDirections.Decrease) |
||||
|
{ |
||||
|
OnDecrement(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs a decrement if conditions allow it.
|
||||
|
/// </summary>
|
||||
|
private void DoIncrement() |
||||
|
{ |
||||
|
if (Spinner == null || (Spinner.ValidSpinDirection & ValidSpinDirections.Increase) == ValidSpinDirections.Increase) |
||||
|
{ |
||||
|
OnIncrement(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected void SyncTextAndValueProperties(DependencyProperty p, string text) |
||||
|
{ |
||||
|
//prevents recursive syncing properties
|
||||
|
if (_isSyncingTextAndValueProperties) |
||||
|
return; |
||||
|
|
||||
|
_isSyncingTextAndValueProperties = true; |
||||
|
|
||||
|
//this only occures when the user typed in the value
|
||||
|
if (InputBase.TextProperty == p) |
||||
|
{ |
||||
|
Value = ConvertTextToValue(text); |
||||
|
} |
||||
|
|
||||
|
Text = ConvertValueToText(); |
||||
|
|
||||
|
#if VS2008
|
||||
|
//there is a bug in .NET 3.5 which will not correctly update the textbox text through binding.
|
||||
|
if (TextBox != null) |
||||
|
TextBox.Text = Text; |
||||
|
#endif
|
||||
|
|
||||
|
_isSyncingTextAndValueProperties = false; |
||||
|
} |
||||
|
|
||||
|
#region Abstract
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Coerces the value.
|
||||
|
/// </summary>
|
||||
|
protected abstract T CoerceValue(T value); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the formatted text to a value.
|
||||
|
/// </summary>
|
||||
|
protected abstract T ConvertTextToValue(string text); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts the value to formatted text.
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
protected abstract string ConvertValueToText(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Called by OnSpin when the spin direction is SpinDirection.Increase.
|
||||
|
/// </summary>
|
||||
|
protected abstract void OnIncrement(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Called by OnSpin when the spin direction is SpinDirection.Descrease.
|
||||
|
/// </summary>
|
||||
|
protected abstract void OnDecrement(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the valid spin directions.
|
||||
|
/// </summary>
|
||||
|
protected abstract void SetValidSpinDirection(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Validates the value and keeps it between the Min and Max values.
|
||||
|
/// </summary>
|
||||
|
/// <param name="value">The value.</param>
|
||||
|
protected abstract void ValidateValue(T value); |
||||
|
|
||||
|
#endregion //Abstract
|
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,215 @@ |
|||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// An adorner that can display one and only one UIElement.
|
||||
|
/// That element can be a panel, which contains multiple other elements.
|
||||
|
/// The element is added to the adorner's visual and logical trees, enabling it to
|
||||
|
/// particpate in dependency property value inheritance, amongst other things.
|
||||
|
/// </summary>
|
||||
|
internal class UIElementAdorner<TElement> |
||||
|
: Adorner |
||||
|
where TElement : UIElement |
||||
|
{ |
||||
|
#region Fields
|
||||
|
|
||||
|
TElement _child = null; |
||||
|
double _offsetLeft = 0; |
||||
|
double _offsetTop = 0; |
||||
|
|
||||
|
#endregion // Fields
|
||||
|
|
||||
|
#region Constructor
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Constructor.
|
||||
|
/// </summary>
|
||||
|
/// <param name="adornedElement">The element to which the adorner will be bound.</param>
|
||||
|
public UIElementAdorner(UIElement adornedElement) |
||||
|
: base(adornedElement) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
#endregion // Constructor
|
||||
|
|
||||
|
#region Public Interface
|
||||
|
|
||||
|
#region Child
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets/sets the child element hosted in the adorner.
|
||||
|
/// </summary>
|
||||
|
public TElement Child |
||||
|
{ |
||||
|
get { return _child; } |
||||
|
set |
||||
|
{ |
||||
|
if (value == _child) |
||||
|
return; |
||||
|
|
||||
|
if (_child != null) |
||||
|
{ |
||||
|
base.RemoveLogicalChild(_child); |
||||
|
base.RemoveVisualChild(_child); |
||||
|
} |
||||
|
|
||||
|
_child = value; |
||||
|
|
||||
|
if (_child != null) |
||||
|
{ |
||||
|
base.AddLogicalChild(_child); |
||||
|
base.AddVisualChild(_child); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion // Child
|
||||
|
|
||||
|
#region GetDesiredTransform
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Override.
|
||||
|
/// </summary>
|
||||
|
/// <param name="transform"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public override GeneralTransform GetDesiredTransform(GeneralTransform transform) |
||||
|
{ |
||||
|
GeneralTransformGroup result = new GeneralTransformGroup(); |
||||
|
result.Children.Add(base.GetDesiredTransform(transform)); |
||||
|
result.Children.Add(new TranslateTransform(_offsetLeft, _offsetTop)); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
#endregion // GetDesiredTransform
|
||||
|
|
||||
|
#region OffsetLeft
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets/sets the horizontal offset of the adorner.
|
||||
|
/// </summary>
|
||||
|
public double OffsetLeft |
||||
|
{ |
||||
|
get { return _offsetLeft; } |
||||
|
set |
||||
|
{ |
||||
|
_offsetLeft = value; |
||||
|
UpdateLocation(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion // OffsetLeft
|
||||
|
|
||||
|
#region SetOffsets
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Updates the location of the adorner in one atomic operation.
|
||||
|
/// </summary>
|
||||
|
public void SetOffsets(double left, double top) |
||||
|
{ |
||||
|
_offsetLeft = left; |
||||
|
_offsetTop = top; |
||||
|
this.UpdateLocation(); |
||||
|
} |
||||
|
|
||||
|
#endregion // SetOffsets
|
||||
|
|
||||
|
#region OffsetTop
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets/sets the vertical offset of the adorner.
|
||||
|
/// </summary>
|
||||
|
public double OffsetTop |
||||
|
{ |
||||
|
get { return _offsetTop; } |
||||
|
set |
||||
|
{ |
||||
|
_offsetTop = value; |
||||
|
UpdateLocation(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion // OffsetTop
|
||||
|
|
||||
|
#endregion // Public Interface
|
||||
|
|
||||
|
#region Protected Overrides
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Override.
|
||||
|
/// </summary>
|
||||
|
/// <param name="constraint"></param>
|
||||
|
/// <returns></returns>
|
||||
|
protected override Size MeasureOverride(Size constraint) |
||||
|
{ |
||||
|
if (_child == null) |
||||
|
return base.MeasureOverride(constraint); |
||||
|
|
||||
|
_child.Measure(constraint); |
||||
|
return _child.DesiredSize; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Override.
|
||||
|
/// </summary>
|
||||
|
/// <param name="finalSize"></param>
|
||||
|
/// <returns></returns>
|
||||
|
protected override Size ArrangeOverride(Size finalSize) |
||||
|
{ |
||||
|
if (_child == null) |
||||
|
return base.ArrangeOverride(finalSize); |
||||
|
|
||||
|
_child.Arrange(new Rect(finalSize)); |
||||
|
return finalSize; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Override.
|
||||
|
/// </summary>
|
||||
|
protected override IEnumerator LogicalChildren |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
ArrayList list = new ArrayList(); |
||||
|
if (_child != null) |
||||
|
list.Add(_child); |
||||
|
return list.GetEnumerator(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Override.
|
||||
|
/// </summary>
|
||||
|
/// <param name="index"></param>
|
||||
|
/// <returns></returns>
|
||||
|
protected override Visual GetVisualChild(int index) |
||||
|
{ |
||||
|
return _child; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Override.
|
||||
|
/// </summary>
|
||||
|
protected override int VisualChildrenCount |
||||
|
{ |
||||
|
get { return _child == null ? 0 : 1; } |
||||
|
} |
||||
|
|
||||
|
#endregion // Protected Overrides
|
||||
|
|
||||
|
#region Private Helpers
|
||||
|
|
||||
|
void UpdateLocation() |
||||
|
{ |
||||
|
AdornerLayer adornerLayer = base.Parent as AdornerLayer; |
||||
|
if (adornerLayer != null) |
||||
|
adornerLayer.Update(base.AdornedElement); |
||||
|
} |
||||
|
|
||||
|
#endregion // Private Helpers
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,245 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Media; |
||||
|
using System.Globalization; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Utilities |
||||
|
{ |
||||
|
static class CalculatorUtilities |
||||
|
{ |
||||
|
public static Calculator.CalculatorButtonType GetCalculatorButtonTypeFromText(string text) |
||||
|
{ |
||||
|
switch (text) |
||||
|
{ |
||||
|
case "0": return Calculator.CalculatorButtonType.Zero; |
||||
|
case "1": return Calculator.CalculatorButtonType.One; |
||||
|
case "2": return Calculator.CalculatorButtonType.Two; |
||||
|
case "3": return Calculator.CalculatorButtonType.Three; |
||||
|
case "4": return Calculator.CalculatorButtonType.Four; |
||||
|
case "5": return Calculator.CalculatorButtonType.Five; |
||||
|
case "6": return Calculator.CalculatorButtonType.Six; |
||||
|
case "7": return Calculator.CalculatorButtonType.Seven; |
||||
|
case "8": return Calculator.CalculatorButtonType.Eight; |
||||
|
case "9": return Calculator.CalculatorButtonType.Nine; |
||||
|
case "+": return Calculator.CalculatorButtonType.Add; |
||||
|
case "-": return Calculator.CalculatorButtonType.Subtract; |
||||
|
case "*": return Calculator.CalculatorButtonType.Multiply; |
||||
|
case "/": return Calculator.CalculatorButtonType.Divide; |
||||
|
case "%": return Calculator.CalculatorButtonType.Percent; |
||||
|
case "\b": return Calculator.CalculatorButtonType.Back; |
||||
|
case "\r": |
||||
|
case "=": return Calculator.CalculatorButtonType.Equal; |
||||
|
} |
||||
|
|
||||
|
//the check for the decimal is not in the switch statement. To help localize we check against the current culture's decimal seperator
|
||||
|
if (text == CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator) |
||||
|
return Calculator.CalculatorButtonType.Decimal; |
||||
|
|
||||
|
//check for the escape key
|
||||
|
if (text == ((char)27).ToString()) |
||||
|
return Calculator.CalculatorButtonType.Clear; |
||||
|
|
||||
|
return Calculator.CalculatorButtonType.None; |
||||
|
} |
||||
|
|
||||
|
public static Button FindButtonByCalculatorButtonType(DependencyObject parent, Calculator.CalculatorButtonType type) |
||||
|
{ |
||||
|
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) |
||||
|
{ |
||||
|
var child = VisualTreeHelper.GetChild(parent, i); |
||||
|
|
||||
|
object buttonType = child.GetValue(Button.CommandParameterProperty); |
||||
|
|
||||
|
if (buttonType != null && (Calculator.CalculatorButtonType)buttonType == type) |
||||
|
{ |
||||
|
return child as Button; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var result = FindButtonByCalculatorButtonType(child, type); |
||||
|
|
||||
|
if (result != null) |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public static string GetCalculatorButtonContent(Calculator.CalculatorButtonType type) |
||||
|
{ |
||||
|
string content = string.Empty; |
||||
|
switch (type) |
||||
|
{ |
||||
|
case Calculator.CalculatorButtonType.Add: |
||||
|
content = "+"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Back: |
||||
|
content = "Back"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Cancel: |
||||
|
content = "CE"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Clear: |
||||
|
content = "C"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Decimal: |
||||
|
content = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Divide: |
||||
|
content = "/"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Eight: |
||||
|
content = "8"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Equal: |
||||
|
content = "="; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Five: |
||||
|
content = "5"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Four: |
||||
|
content = "4"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Fraction: |
||||
|
content = "1/x"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MAdd: |
||||
|
content = "M+"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MC: |
||||
|
content = "MC"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MR: |
||||
|
content = "MR"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MS: |
||||
|
content = "MS"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.MSub: |
||||
|
content = "M-"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Multiply: |
||||
|
content = "*"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Nine: |
||||
|
content = "9"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.None: |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.One: |
||||
|
content = "1"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Percent: |
||||
|
content = "%"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Seven: |
||||
|
content = "7"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Negate: |
||||
|
content = "+/-"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Six: |
||||
|
content = "6"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Sqrt: |
||||
|
content = "Sqrt"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Subtract: |
||||
|
content = "-"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Three: |
||||
|
content = "3"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Two: |
||||
|
content = "2"; |
||||
|
break; |
||||
|
case Calculator.CalculatorButtonType.Zero: |
||||
|
content = "0"; |
||||
|
break; |
||||
|
} |
||||
|
return content; |
||||
|
} |
||||
|
|
||||
|
public static bool IsDigit(Calculator.CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
switch (buttonType) |
||||
|
{ |
||||
|
case Calculator.CalculatorButtonType.Zero: |
||||
|
case Calculator.CalculatorButtonType.One: |
||||
|
case Calculator.CalculatorButtonType.Two: |
||||
|
case Calculator.CalculatorButtonType.Three: |
||||
|
case Calculator.CalculatorButtonType.Four: |
||||
|
case Calculator.CalculatorButtonType.Five: |
||||
|
case Calculator.CalculatorButtonType.Six: |
||||
|
case Calculator.CalculatorButtonType.Seven: |
||||
|
case Calculator.CalculatorButtonType.Eight: |
||||
|
case Calculator.CalculatorButtonType.Nine: |
||||
|
case Calculator.CalculatorButtonType.Decimal: |
||||
|
return true; |
||||
|
default: |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static bool IsMemory(Calculator.CalculatorButtonType buttonType) |
||||
|
{ |
||||
|
switch (buttonType) |
||||
|
{ |
||||
|
case Calculator.CalculatorButtonType.MAdd: |
||||
|
case Calculator.CalculatorButtonType.MC: |
||||
|
case Calculator.CalculatorButtonType.MR: |
||||
|
case Calculator.CalculatorButtonType.MS: |
||||
|
case Calculator.CalculatorButtonType.MSub: |
||||
|
return true; |
||||
|
default: |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static decimal ParseDecimal(string text) |
||||
|
{ |
||||
|
return Decimal.Parse(text, CultureInfo.CurrentCulture); |
||||
|
} |
||||
|
|
||||
|
public static decimal Add(decimal firstNumber, decimal secondNumber) |
||||
|
{ |
||||
|
return firstNumber + secondNumber; |
||||
|
} |
||||
|
|
||||
|
public static decimal Subtract(decimal firstNumber, decimal secondNumber) |
||||
|
{ |
||||
|
return firstNumber - secondNumber; |
||||
|
} |
||||
|
|
||||
|
public static decimal Multiply(decimal firstNumber, decimal secondNumber) |
||||
|
{ |
||||
|
return firstNumber * secondNumber; |
||||
|
} |
||||
|
|
||||
|
public static decimal Divide(decimal firstNumber, decimal secondNumber) |
||||
|
{ |
||||
|
return firstNumber / secondNumber; |
||||
|
} |
||||
|
|
||||
|
public static decimal Percent(decimal firstNumber, decimal secondNumber) |
||||
|
{ |
||||
|
return firstNumber * secondNumber / 100M; |
||||
|
} |
||||
|
|
||||
|
public static decimal SquareRoot(decimal operand) |
||||
|
{ |
||||
|
return Convert.ToDecimal(Math.Sqrt(Convert.ToDouble(operand))); |
||||
|
} |
||||
|
|
||||
|
public static decimal Fraction(decimal operand) |
||||
|
{ |
||||
|
return 1 / operand; |
||||
|
} |
||||
|
|
||||
|
public static decimal Negate(decimal operand) |
||||
|
{ |
||||
|
return operand * -1M; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,177 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Windows.Media; |
||||
|
using System.Reflection; |
||||
|
using System.Collections.Generic; |
||||
|
using Microsoft.Windows.Controls.Primitives; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Utilities |
||||
|
{ |
||||
|
static class ColorUtilities |
||||
|
{ |
||||
|
public static readonly Dictionary<string, Color> KnownColors = GetKnownColors(); |
||||
|
|
||||
|
public static string GetColorName(this Color color) |
||||
|
{ |
||||
|
string colorName = KnownColors.Where(kvp => kvp.Value.Equals(color)).Select(kvp => kvp.Key).FirstOrDefault(); |
||||
|
|
||||
|
if (String.IsNullOrEmpty(colorName)) |
||||
|
colorName = color.ToString(); |
||||
|
|
||||
|
return colorName; |
||||
|
} |
||||
|
|
||||
|
private static Dictionary<string, Color> GetKnownColors() |
||||
|
{ |
||||
|
var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public); |
||||
|
return colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts an RGB color to an HSV color.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r"></param>
|
||||
|
/// <param name="b"></param>
|
||||
|
/// <param name="g"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static HsvColor ConvertRgbToHsv(int r, int b, int g) |
||||
|
{ |
||||
|
double delta, min; |
||||
|
double h = 0, s, v; |
||||
|
|
||||
|
min = Math.Min(Math.Min(r, g), b); |
||||
|
v = Math.Max(Math.Max(r, g), b); |
||||
|
delta = v - min; |
||||
|
|
||||
|
if (v == 0.0) |
||||
|
{ |
||||
|
s = 0; |
||||
|
} |
||||
|
else |
||||
|
s = delta / v; |
||||
|
|
||||
|
if (s == 0) |
||||
|
h = 0.0; |
||||
|
|
||||
|
else |
||||
|
{ |
||||
|
if (r == v) |
||||
|
h = (g - b) / delta; |
||||
|
else if (g == v) |
||||
|
h = 2 + (b - r) / delta; |
||||
|
else if (b == v) |
||||
|
h = 4 + (r - g) / delta; |
||||
|
|
||||
|
h *= 60; |
||||
|
if (h < 0.0) |
||||
|
h = h + 360; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return new HsvColor { H = h, S = s, V = v / 255 }; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts an HSV color to an RGB color.
|
||||
|
/// </summary>
|
||||
|
/// <param name="h"></param>
|
||||
|
/// <param name="s"></param>
|
||||
|
/// <param name="v"></param>
|
||||
|
/// <returns></returns>
|
||||
|
public static Color ConvertHsvToRgb(double h, double s, double v) |
||||
|
{ |
||||
|
double r = 0, g = 0, b = 0; |
||||
|
|
||||
|
if (s == 0) |
||||
|
{ |
||||
|
r = v; |
||||
|
g = v; |
||||
|
b = v; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
int i; |
||||
|
double f, p, q, t; |
||||
|
|
||||
|
if (h == 360) |
||||
|
h = 0; |
||||
|
else |
||||
|
h = h / 60; |
||||
|
|
||||
|
i = (int)Math.Truncate(h); |
||||
|
f = h - i; |
||||
|
|
||||
|
p = v * (1.0 - s); |
||||
|
q = v * (1.0 - (s * f)); |
||||
|
t = v * (1.0 - (s * (1.0 - f))); |
||||
|
|
||||
|
switch (i) |
||||
|
{ |
||||
|
case 0: |
||||
|
{ |
||||
|
r = v; |
||||
|
g = t; |
||||
|
b = p; |
||||
|
break; |
||||
|
} |
||||
|
case 1: |
||||
|
{ |
||||
|
r = q; |
||||
|
g = v; |
||||
|
b = p; |
||||
|
break; |
||||
|
} |
||||
|
case 2: |
||||
|
{ |
||||
|
r = p; |
||||
|
g = v; |
||||
|
b = t; |
||||
|
break; |
||||
|
} |
||||
|
case 3: |
||||
|
{ |
||||
|
r = p; |
||||
|
g = q; |
||||
|
b = v; |
||||
|
break; |
||||
|
} |
||||
|
case 4: |
||||
|
{ |
||||
|
r = t; |
||||
|
g = p; |
||||
|
b = v; |
||||
|
break; |
||||
|
} |
||||
|
default: |
||||
|
{ |
||||
|
r = v; |
||||
|
g = p; |
||||
|
b = q; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
return Color.FromArgb(255, (byte)(r * 255), (byte)(g * 255), (byte)(b * 255)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Generates a list of colors with hues ranging from 0 360 and a saturation and value of 1.
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
public static List<Color> GenerateHsvSpectrum() |
||||
|
{ |
||||
|
List<Color> colorsList = new List<Color>(8); |
||||
|
|
||||
|
for (int i = 0; i < 29; i++) |
||||
|
{ |
||||
|
colorsList.Add(ColorUtilities.ConvertHsvToRgb(i * 12, 1, 1)); |
||||
|
} |
||||
|
|
||||
|
colorsList.Add(ColorUtilities.ConvertHsvToRgb(0, 1, 1)); |
||||
|
|
||||
|
return colorsList; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Core.Utilities |
||||
|
{ |
||||
|
public class ContextMenuUtilities |
||||
|
{ |
||||
|
public static readonly DependencyProperty OpenOnMouseLeftButtonClickProperty = DependencyProperty.RegisterAttached("OpenOnMouseLeftButtonClick", typeof(bool), typeof(ContextMenuUtilities), new FrameworkPropertyMetadata(false, OpenOnMouseLeftButtonClickChanged)); |
||||
|
public static void SetOpenOnMouseLeftButtonClick(FrameworkElement element, bool value) |
||||
|
{ |
||||
|
element.SetValue(OpenOnMouseLeftButtonClickProperty, value); |
||||
|
} |
||||
|
public static bool GetOpenOnMouseLeftButtonClick(FrameworkElement element) |
||||
|
{ |
||||
|
return (bool)element.GetValue(OpenOnMouseLeftButtonClickProperty); |
||||
|
} |
||||
|
|
||||
|
public static void OpenOnMouseLeftButtonClickChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
var control = (FrameworkElement)sender; |
||||
|
if ((bool)e.NewValue) |
||||
|
{ |
||||
|
control.PreviewMouseLeftButtonDown += (s, args) => |
||||
|
{ |
||||
|
if (control.ContextMenu != null) |
||||
|
{ |
||||
|
control.ContextMenu.PlacementTarget = control; |
||||
|
control.ContextMenu.IsOpen = true; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
//TODO: remove handler when set to false
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,145 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Input; |
||||
|
#if VS2008
|
||||
|
using Microsoft.Windows.Controls.Primitives; |
||||
|
#else
|
||||
|
using System.Windows.Controls.Primitives; |
||||
|
#endif
|
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class DateTimePicker : DateTimeUpDown |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private Calendar _calendar; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region IsOpen
|
||||
|
|
||||
|
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(DateTimePicker), new UIPropertyMetadata(false)); |
||||
|
public bool IsOpen |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsOpenProperty); } |
||||
|
set { SetValue(IsOpenProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //IsOpen
|
||||
|
|
||||
|
#region TimeWatermark
|
||||
|
|
||||
|
public static readonly DependencyProperty TimeWatermarkProperty = DependencyProperty.Register("TimeWatermark", typeof(object), typeof(DateTimePicker), new UIPropertyMetadata(null)); |
||||
|
public object TimeWatermark |
||||
|
{ |
||||
|
get { return (object)GetValue(TimeWatermarkProperty); } |
||||
|
set { SetValue(TimeWatermarkProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //TimeWatermark
|
||||
|
|
||||
|
#region TimeWatermarkTemplate
|
||||
|
|
||||
|
public static readonly DependencyProperty TimeWatermarkTemplateProperty = DependencyProperty.Register("TimeWatermarkTemplate", typeof(DataTemplate), typeof(DateTimePicker), new UIPropertyMetadata(null)); |
||||
|
public DataTemplate TimeWatermarkTemplate |
||||
|
{ |
||||
|
get { return (DataTemplate)GetValue(TimeWatermarkTemplateProperty); } |
||||
|
set { SetValue(TimeWatermarkTemplateProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //TimeWatermarkTemplate
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static DateTimePicker() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DateTimePicker), new FrameworkPropertyMetadata(typeof(DateTimePicker))); |
||||
|
} |
||||
|
|
||||
|
public DateTimePicker() |
||||
|
{ |
||||
|
Keyboard.AddKeyDownHandler(this, OnKeyDown); |
||||
|
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_calendar = (Calendar)GetTemplateChild("Part_Calendar"); |
||||
|
_calendar.SelectedDatesChanged += Calendar_SelectedDatesChanged; |
||||
|
_calendar.SelectedDate = Value ?? null; |
||||
|
} |
||||
|
|
||||
|
protected override void OnPreviewMouseUp(MouseButtonEventArgs e) |
||||
|
{ |
||||
|
if (Mouse.Captured is CalendarItem) |
||||
|
Mouse.Capture(null); |
||||
|
} |
||||
|
|
||||
|
protected override void OnValueChanged(DateTime? oldValue, DateTime? newValue) |
||||
|
{ |
||||
|
if (_calendar != null && _calendar.SelectedDate.HasValue && newValue.HasValue && _calendar.SelectedDate.Value != newValue.Value) |
||||
|
{ |
||||
|
_calendar.SelectedDate = newValue; |
||||
|
_calendar.DisplayDate = newValue.Value; |
||||
|
} |
||||
|
|
||||
|
base.OnValueChanged(oldValue, newValue); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
private void OnKeyDown(object sender, KeyEventArgs e) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Escape: |
||||
|
case Key.Tab: |
||||
|
{ |
||||
|
CloseDateTimePicker(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
CloseDateTimePicker(); |
||||
|
} |
||||
|
|
||||
|
void Calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e) |
||||
|
{ |
||||
|
if (e.AddedItems.Count > 0) |
||||
|
{ |
||||
|
var newDate = (DateTime?)e.AddedItems[0]; |
||||
|
Value = newDate; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void CloseDateTimePicker() |
||||
|
{ |
||||
|
if (IsOpen) |
||||
|
IsOpen = false; |
||||
|
ReleaseMouseCapture(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,124 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"> |
||||
|
|
||||
|
<coreConverters:InverseBoolConverter x:Key="InverseBoolConverter" /> |
||||
|
|
||||
|
<DataTemplate x:Key="DefaultWatermarkTemplate"> |
||||
|
<ContentControl Content="{Binding}" Foreground="Gray" Focusable="False" /> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<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 x:Key="DateTimePickerToggleButtonStyle" TargetType="ToggleButton"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="ToggleButton"> |
||||
|
<Grid SnapsToDevicePixels="True"> |
||||
|
<chrome:ButtonChrome x:Name="ToggleButtonChrome" |
||||
|
CornerRadius="0,2.75,2.75,0" |
||||
|
RenderMouseOver="{TemplateBinding IsMouseOver}" |
||||
|
RenderPressed="{TemplateBinding IsPressed}" /> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> |
||||
|
|
||||
|
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Grid.Column="1" Margin="5"> |
||||
|
<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> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- DateTimePicker --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:DateTimePicker}"> |
||||
|
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Right" /> |
||||
|
<Setter Property="TextAlignment" Value="Right" /> |
||||
|
<Setter Property="TimeWatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
<Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:DateTimePicker}"> |
||||
|
<Border> |
||||
|
<Grid> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*" /> |
||||
|
<ColumnDefinition Width="Auto" /> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<local:ButtonSpinner x:Name="Spinner" IsTabStop="False" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
AllowSpin="{TemplateBinding AllowSpin}" ShowButtonSpinner="{TemplateBinding ShowButtonSpinner}"> |
||||
|
<local:WatermarkTextBox x:Name="TextBox" BorderThickness="0" |
||||
|
Background="{TemplateBinding Background}" |
||||
|
FontFamily="{TemplateBinding FontFamily}" |
||||
|
FontSize="{TemplateBinding FontSize}" |
||||
|
FontStretch="{TemplateBinding FontStretch}" |
||||
|
FontStyle="{TemplateBinding FontStyle}" |
||||
|
FontWeight="{TemplateBinding FontWeight}" |
||||
|
Foreground="{TemplateBinding Foreground}" |
||||
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
IsReadOnly="{Binding IsEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" |
||||
|
MinWidth="20" AcceptsReturn="False" |
||||
|
TextAlignment="{TemplateBinding TextAlignment}" |
||||
|
TextWrapping="NoWrap" |
||||
|
TabIndex="{TemplateBinding TabIndex}" |
||||
|
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Watermark="{TemplateBinding Watermark}" |
||||
|
WatermarkTemplate="{TemplateBinding WatermarkTemplate}"/> |
||||
|
</local:ButtonSpinner> |
||||
|
<ToggleButton x:Name="_calendarToggleButton" Grid.Column="1" Background="White" |
||||
|
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Style="{StaticResource DateTimePickerToggleButtonStyle}" |
||||
|
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}"/> |
||||
|
</Grid> |
||||
|
<Popup IsOpen="{Binding IsChecked, ElementName=_calendarToggleButton}" StaysOpen="False"> |
||||
|
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource PopupDarkBorderBrush}" Padding="3"> |
||||
|
<StackPanel> |
||||
|
<Calendar x:Name="Part_Calendar" BorderThickness="0" /> |
||||
|
<local:TimePicker x:Name="Part_TimeUpDown" |
||||
|
Format="ShortTime" |
||||
|
Value="{Binding Value, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Watermark="{TemplateBinding TimeWatermark}" |
||||
|
WatermarkTemplate="{TemplateBinding TimeWatermarkTemplate}"/> |
||||
|
</StackPanel> |
||||
|
</Border> |
||||
|
</Popup> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,19 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public enum DateTimeFormat |
||||
|
{ |
||||
|
Custom, |
||||
|
FullDateTime, |
||||
|
LongDate, |
||||
|
LongTime, |
||||
|
MonthDay, |
||||
|
RFC1123, |
||||
|
ShortDate, |
||||
|
ShortTime, |
||||
|
SortableDateTime, |
||||
|
UniversalSortableDateTime, |
||||
|
YearMonth |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
internal class DateTimeInfo |
||||
|
{ |
||||
|
public string Content { get; set; } |
||||
|
public string Format { get; set; } |
||||
|
public bool IsReadOnly { get; set; } |
||||
|
public int Length { get; set; } |
||||
|
public int StartPosition { get; set; } |
||||
|
public DateTimePart Type { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,134 @@ |
|||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Globalization; |
||||
|
using System.Text; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.RegularExpressions; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
internal class DateTimeParser |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
private DateTimeFormatInfo DateTimeFormatInfo { get; set; } |
||||
|
|
||||
|
public string Format { get; set; } |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
public DateTimeParser(DateTimeFormatInfo dateTimeFormatInfo) |
||||
|
{ |
||||
|
DateTimeFormatInfo = dateTimeFormatInfo; |
||||
|
} |
||||
|
|
||||
|
public DateTimeParser(DateTimeFormatInfo dateTimeFormatInfo, string format) |
||||
|
{ |
||||
|
DateTimeFormatInfo = dateTimeFormatInfo; |
||||
|
Format = format; |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
public bool TryParse(string value, out DateTime result, DateTime currentDate) |
||||
|
{ |
||||
|
bool success = false; |
||||
|
result = currentDate; |
||||
|
|
||||
|
if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(Format)) |
||||
|
return false; |
||||
|
|
||||
|
var dateTimeString = ResolveDateTimeString(value, currentDate); |
||||
|
|
||||
|
if (!String.IsNullOrEmpty(dateTimeString)) |
||||
|
success = DateTime.TryParse(dateTimeString, DateTimeFormatInfo, DateTimeStyles.None, out result); |
||||
|
|
||||
|
if (!success) |
||||
|
result = currentDate; |
||||
|
|
||||
|
return success; |
||||
|
} |
||||
|
|
||||
|
private string ResolveDateTimeString(string dateTime, DateTime currentDate) |
||||
|
{ |
||||
|
Dictionary<string, string> dateParts = GetDateParts(currentDate); |
||||
|
string[] timeParts = new string[3] { currentDate.Hour.ToString(), currentDate.Minute.ToString(), currentDate.Second.ToString() }; |
||||
|
string designator = ""; |
||||
|
string[] dateTimeSeparators = new string[] { ",", " ", "-", DateTimeFormatInfo.DateSeparator, DateTimeFormatInfo.TimeSeparator }; |
||||
|
|
||||
|
var dateTimeParts = dateTime.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); |
||||
|
var formats = Format.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); |
||||
|
|
||||
|
//something went wrong
|
||||
|
if (dateTimeParts.Count != formats.Count) |
||||
|
return string.Empty; |
||||
|
|
||||
|
for (int i = 0; i < formats.Count; i++) |
||||
|
{ |
||||
|
var format = formats[i]; |
||||
|
if (!format.Contains("ddd") && !format.Contains("GMT")) |
||||
|
{ |
||||
|
if (format.Contains("M")) |
||||
|
dateParts["Month"] = dateTimeParts[i]; |
||||
|
else if (format.Contains("d")) |
||||
|
dateParts["Day"] = dateTimeParts[i]; |
||||
|
else if (format.Contains("y")) |
||||
|
{ |
||||
|
dateParts["Year"] = dateTimeParts[i]; |
||||
|
|
||||
|
if (dateParts["Year"].Length == 2) |
||||
|
dateParts["Year"] = string.Format("{0}{1}", currentDate.Year / 100, dateParts["Year"]); |
||||
|
} |
||||
|
else if (format.Contains("h") || format.Contains("H")) |
||||
|
timeParts[0] = dateTimeParts[i]; |
||||
|
else if (format.Contains("m")) |
||||
|
timeParts[1] = dateTimeParts[i]; |
||||
|
else if (format.Contains("s")) |
||||
|
timeParts[2] = dateTimeParts[i]; |
||||
|
else if (format.Contains("t")) |
||||
|
designator = dateTimeParts[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var date = string.Join(DateTimeFormatInfo.DateSeparator, dateParts.Select(x => x.Value).ToArray()); |
||||
|
var time = string.Join(DateTimeFormatInfo.TimeSeparator, timeParts); |
||||
|
|
||||
|
return String.Format("{0} {1} {2}", date, time, designator); |
||||
|
} |
||||
|
|
||||
|
private Dictionary<string, string> GetDateParts(DateTime currentDate) |
||||
|
{ |
||||
|
Dictionary<string, string> dateParts = new Dictionary<string, string>(); |
||||
|
var dateFormatParts = DateTimeFormatInfo.ShortDatePattern.Split(new string[] { DateTimeFormatInfo.DateSeparator }, StringSplitOptions.RemoveEmptyEntries).ToList(); |
||||
|
dateFormatParts.ForEach(item => |
||||
|
{ |
||||
|
string key = string.Empty; |
||||
|
string value = string.Empty; |
||||
|
|
||||
|
if (item.Contains("M")) |
||||
|
{ |
||||
|
key = "Month"; |
||||
|
value = currentDate.Month.ToString(); |
||||
|
} |
||||
|
else if (item.Contains("d")) |
||||
|
{ |
||||
|
key = "Day"; |
||||
|
value = currentDate.Day.ToString(); |
||||
|
} |
||||
|
else if (item.Contains("y")) |
||||
|
{ |
||||
|
key = "Year"; |
||||
|
value = currentDate.Year.ToString(); |
||||
|
} |
||||
|
dateParts.Add(key, value); |
||||
|
}); |
||||
|
return dateParts; |
||||
|
} |
||||
|
|
||||
|
#endregion // Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public enum DateTimePart |
||||
|
{ |
||||
|
Day, |
||||
|
DayName, |
||||
|
AmPmDesignator, |
||||
|
Millisecond, |
||||
|
Hour12, |
||||
|
Hour24, |
||||
|
Minute, |
||||
|
Month, |
||||
|
MonthName, |
||||
|
Other, |
||||
|
Period, |
||||
|
TimeZone, |
||||
|
Second, |
||||
|
Year |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,563 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using Microsoft.Windows.Controls.Primitives; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class DateTimeUpDown : UpDownBase<DateTime?> |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private List<DateTimeInfo> _dateTimeInfoList = new List<DateTimeInfo>(); |
||||
|
private DateTimeInfo _selectedDateTimeInfo; |
||||
|
private bool _fireSelectionChangedEvent = true; |
||||
|
|
||||
|
private DateTimeParser _dateTimeParser; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
private DateTimeFormatInfo DateTimeFormatInfo { get; set; } |
||||
|
|
||||
|
#region DefaultValue
|
||||
|
|
||||
|
public static readonly DependencyProperty DefaultValueProperty = DependencyProperty.Register("DefaultValue", typeof(DateTime), typeof(DateTimeUpDown), new UIPropertyMetadata(DateTime.Now)); |
||||
|
public DateTime DefaultValue |
||||
|
{ |
||||
|
get { return (DateTime)GetValue(DefaultValueProperty); } |
||||
|
set { SetValue(DefaultValueProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //DefaultValue
|
||||
|
|
||||
|
#region Format
|
||||
|
|
||||
|
public static readonly DependencyProperty FormatProperty = DependencyProperty.Register("Format", typeof(DateTimeFormat), typeof(DateTimeUpDown), new UIPropertyMetadata(DateTimeFormat.FullDateTime, OnFormatChanged)); |
||||
|
public DateTimeFormat Format |
||||
|
{ |
||||
|
get { return (DateTimeFormat)GetValue(FormatProperty); } |
||||
|
set { SetValue(FormatProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnFormatChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
DateTimeUpDown dateTimeUpDown = o as DateTimeUpDown; |
||||
|
if (dateTimeUpDown != null) |
||||
|
dateTimeUpDown.OnFormatChanged((DateTimeFormat)e.OldValue, (DateTimeFormat)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnFormatChanged(DateTimeFormat oldValue, DateTimeFormat newValue) |
||||
|
{ |
||||
|
_dateTimeParser.Format = GetFormatString(newValue); |
||||
|
InitializeDateTimeInfoListAndParseValue(); |
||||
|
|
||||
|
//I forgot why I set the text here. I believe it had to deal with databinding to the format. Either way we need to make sure there is a value before we try to set the text.
|
||||
|
if (Value.HasValue) |
||||
|
Text = ConvertValueToText(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Format
|
||||
|
|
||||
|
#region FormatString
|
||||
|
|
||||
|
public static readonly DependencyProperty FormatStringProperty = DependencyProperty.Register("FormatString", typeof(string), typeof(DateTimeUpDown), new UIPropertyMetadata(default(String), OnFormatStringChanged)); |
||||
|
public string FormatString |
||||
|
{ |
||||
|
get { return (string)GetValue(FormatStringProperty); } |
||||
|
set { SetValue(FormatStringProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnFormatStringChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
DateTimeUpDown dateTimeUpDown = o as DateTimeUpDown; |
||||
|
if (dateTimeUpDown != null) |
||||
|
dateTimeUpDown.OnFormatStringChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnFormatStringChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(newValue)) |
||||
|
throw new ArgumentException("FormatString should be specified.", "newValue"); |
||||
|
|
||||
|
_dateTimeParser.Format = newValue; |
||||
|
InitializeDateTimeInfoListAndParseValue(); |
||||
|
} |
||||
|
|
||||
|
#endregion //FormatString
|
||||
|
|
||||
|
#region Maximum
|
||||
|
|
||||
|
|
||||
|
|
||||
|
#endregion //Maximum
|
||||
|
|
||||
|
#region Minimum
|
||||
|
|
||||
|
|
||||
|
|
||||
|
#endregion //Minimum
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static DateTimeUpDown() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DateTimeUpDown), new FrameworkPropertyMetadata(typeof(DateTimeUpDown))); |
||||
|
} |
||||
|
|
||||
|
public DateTimeUpDown() |
||||
|
{ |
||||
|
DateTimeFormatInfo = DateTimeFormatInfo.GetInstance(CultureInfo); |
||||
|
_dateTimeParser = new DateTimeParser(DateTimeFormatInfo, GetFormatString(Format)); |
||||
|
InitializeDateTimeInfoList(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
TextBox.SelectionChanged += TextBox_SelectionChanged; |
||||
|
} |
||||
|
|
||||
|
protected override DateTime? CoerceValue(DateTime? value) |
||||
|
{ |
||||
|
//TODO: implement Minimum and Maximum
|
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
protected override void OnIncrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
UpdateDateTime(1); |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override void OnDecrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
UpdateDateTime(-1); |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override void OnPreviewKeyDown(KeyEventArgs e) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Enter: |
||||
|
{ |
||||
|
if (IsEditable) |
||||
|
{ |
||||
|
_fireSelectionChangedEvent = false; |
||||
|
BindingExpression binding = BindingOperations.GetBindingExpression(TextBox, System.Windows.Controls.TextBox.TextProperty); |
||||
|
binding.UpdateSource(); |
||||
|
_fireSelectionChangedEvent = true; |
||||
|
e.Handled = true; |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
default: |
||||
|
{ |
||||
|
_fireSelectionChangedEvent = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
base.OnPreviewKeyDown(e); |
||||
|
} |
||||
|
|
||||
|
protected override void OnTextChanged(string previousValue, string currentValue) |
||||
|
{ |
||||
|
//TODO: clean this up and make sure it doesn't fire recursively
|
||||
|
if (String.IsNullOrEmpty(currentValue)) |
||||
|
{ |
||||
|
Value = null; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
DateTime current = Value.HasValue ? Value.Value : DateTime.Now; |
||||
|
DateTime result; |
||||
|
var success = _dateTimeParser.TryParse(currentValue, out result, current); |
||||
|
|
||||
|
SyncTextAndValueProperties(InputBase.TextProperty, result.ToString()); |
||||
|
} |
||||
|
|
||||
|
protected override DateTime? ConvertTextToValue(string text) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(text)) |
||||
|
return null; |
||||
|
|
||||
|
return DateTime.Parse(text, CultureInfo.CurrentCulture); |
||||
|
} |
||||
|
|
||||
|
protected override string ConvertValueToText() |
||||
|
{ |
||||
|
if (Value == null) return string.Empty; |
||||
|
|
||||
|
DateTime dt = DateTime.Parse(Value.ToString(), CultureInfo); |
||||
|
return dt.ToString(GetFormatString(Format), CultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected override void SetValidSpinDirection() |
||||
|
{ |
||||
|
//TODO: implement Minimum and Maximum
|
||||
|
} |
||||
|
|
||||
|
protected override void OnValueChanged(DateTime? oldValue, DateTime? newValue) |
||||
|
{ |
||||
|
//whenever the value changes we need to parse out the value into out DateTimeInfo segments so we can keep track of the individual pieces
|
||||
|
//but only if it is not null
|
||||
|
if (newValue != null) |
||||
|
ParseValueIntoDateTimeInfo(); |
||||
|
|
||||
|
base.OnValueChanged(oldValue, newValue); |
||||
|
} |
||||
|
|
||||
|
protected override void ValidateValue(DateTime? value) |
||||
|
{ |
||||
|
//TODO: implement min/max
|
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Hanlders
|
||||
|
|
||||
|
void TextBox_SelectionChanged(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (_fireSelectionChangedEvent) |
||||
|
PerformMouseSelection(); |
||||
|
else |
||||
|
_fireSelectionChangedEvent = true; |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Hanlders
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void InitializeDateTimeInfoListAndParseValue() |
||||
|
{ |
||||
|
InitializeDateTimeInfoList(); |
||||
|
if (Value != null) |
||||
|
ParseValueIntoDateTimeInfo(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeDateTimeInfoList() |
||||
|
{ |
||||
|
_dateTimeInfoList.Clear(); |
||||
|
|
||||
|
string format = GetFormatString(Format); |
||||
|
|
||||
|
if (format == null) |
||||
|
return; |
||||
|
|
||||
|
while (format.Length > 0) |
||||
|
{ |
||||
|
int elementLength = GetElementLengthByFormat(format); |
||||
|
DateTimeInfo info = null; |
||||
|
|
||||
|
switch (format[0]) |
||||
|
{ |
||||
|
case '"': |
||||
|
case '\'': |
||||
|
{ |
||||
|
int closingQuotePosition = format.IndexOf(format[0], 1); |
||||
|
info = new DateTimeInfo { IsReadOnly = true, Type = DateTimePart.Other, Length = 1, Content = format.Substring(1, Math.Max(1, closingQuotePosition - 1)) }; |
||||
|
elementLength = Math.Max(1, closingQuotePosition + 1); |
||||
|
break; |
||||
|
} |
||||
|
case 'D': |
||||
|
case 'd': |
||||
|
{ |
||||
|
string d = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
d = "%" + d; |
||||
|
|
||||
|
if (elementLength > 2) |
||||
|
info = new DateTimeInfo { IsReadOnly = true, Type = DateTimePart.DayName, Format = d }; |
||||
|
else |
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Day, Format = d }; |
||||
|
break; |
||||
|
} |
||||
|
case 'F': |
||||
|
case 'f': |
||||
|
{ |
||||
|
string f = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
f = "%" + f; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Millisecond, Format = f }; |
||||
|
break; |
||||
|
} |
||||
|
case 'h': |
||||
|
{ |
||||
|
string h = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
h = "%" + h; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Hour12, Format = h }; |
||||
|
break; |
||||
|
} |
||||
|
case 'H': |
||||
|
{ |
||||
|
string H = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
H = "%" + H; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Hour24, Format = H }; |
||||
|
break; |
||||
|
} |
||||
|
case 'M': |
||||
|
{ |
||||
|
string M = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
M = "%" + M; |
||||
|
|
||||
|
if (elementLength >= 3) |
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.MonthName, Format = M }; |
||||
|
else |
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Month, Format = M }; |
||||
|
break; |
||||
|
} |
||||
|
case 'S': |
||||
|
case 's': |
||||
|
{ |
||||
|
string s = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
s = "%" + s; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Second, Format = s }; |
||||
|
break; |
||||
|
} |
||||
|
case 'T': |
||||
|
case 't': |
||||
|
{ |
||||
|
string t = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
t = "%" + t; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.AmPmDesignator, Format = t }; |
||||
|
break; |
||||
|
} |
||||
|
case 'Y': |
||||
|
case 'y': |
||||
|
{ |
||||
|
string y = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
y = "%" + y; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Year, Format = y }; |
||||
|
break; |
||||
|
} |
||||
|
case '\\': |
||||
|
{ |
||||
|
if (format.Length >= 2) |
||||
|
{ |
||||
|
info = new DateTimeInfo { IsReadOnly = true, Content = format.Substring(1, 1), Length = 1, Type = DateTimePart.Other }; |
||||
|
elementLength = 2; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
case 'g': |
||||
|
{ |
||||
|
string g = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
g = "%" + g; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = true, Type = DateTimePart.Period, Format = format.Substring(0, elementLength) }; |
||||
|
break; |
||||
|
} |
||||
|
case 'm': |
||||
|
{ |
||||
|
string m = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
m = "%" + m; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = false, Type = DateTimePart.Minute, Format = m }; |
||||
|
break; |
||||
|
} |
||||
|
case 'z': |
||||
|
{ |
||||
|
string z = format.Substring(0, elementLength); |
||||
|
if (elementLength == 1) |
||||
|
z = "%" + z; |
||||
|
|
||||
|
info = new DateTimeInfo { IsReadOnly = true, Type = DateTimePart.TimeZone, Format = z }; |
||||
|
break; |
||||
|
} |
||||
|
default: |
||||
|
{ |
||||
|
elementLength = 1; |
||||
|
info = new DateTimeInfo { IsReadOnly = true, Length = 1, Content = format[0].ToString(), Type = DateTimePart.Other }; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
_dateTimeInfoList.Add(info); |
||||
|
format = format.Substring(elementLength); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static int GetElementLengthByFormat(string format) |
||||
|
{ |
||||
|
for (int i = 1; i < format.Length; i++) |
||||
|
{ |
||||
|
if (String.Compare(format[i].ToString(), format[0].ToString(), false) != 0) |
||||
|
{ |
||||
|
return i; |
||||
|
} |
||||
|
} |
||||
|
return format.Length; |
||||
|
} |
||||
|
|
||||
|
private void ParseValueIntoDateTimeInfo() |
||||
|
{ |
||||
|
string text = string.Empty; |
||||
|
|
||||
|
_dateTimeInfoList.ForEach(info => |
||||
|
{ |
||||
|
if (info.Format == null) |
||||
|
{ |
||||
|
info.StartPosition = text.Length; |
||||
|
info.Length = info.Content.Length; |
||||
|
text += info.Content; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
DateTime date = DateTime.Parse(Value.ToString()); |
||||
|
info.StartPosition = text.Length; |
||||
|
info.Content = date.ToString(info.Format, DateTimeFormatInfo); |
||||
|
info.Length = info.Content.Length; |
||||
|
text += info.Content; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void PerformMouseSelection() |
||||
|
{ |
||||
|
_dateTimeInfoList.ForEach(info => |
||||
|
{ |
||||
|
if ((info.StartPosition <= TextBox.SelectionStart) && (TextBox.SelectionStart < (info.StartPosition + info.Length))) |
||||
|
{ |
||||
|
Select(info); |
||||
|
return; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void Select(DateTimeInfo info) |
||||
|
{ |
||||
|
_fireSelectionChangedEvent = false; |
||||
|
TextBox.Select(info.StartPosition, info.Length); |
||||
|
_fireSelectionChangedEvent = true; |
||||
|
_selectedDateTimeInfo = info; |
||||
|
} |
||||
|
|
||||
|
private string GetFormatString(DateTimeFormat dateTimeFormat) |
||||
|
{ |
||||
|
switch (dateTimeFormat) |
||||
|
{ |
||||
|
case DateTimeFormat.ShortDate: |
||||
|
return DateTimeFormatInfo.ShortDatePattern; |
||||
|
case DateTimeFormat.LongDate: |
||||
|
return DateTimeFormatInfo.LongDatePattern; |
||||
|
case DateTimeFormat.ShortTime: |
||||
|
return DateTimeFormatInfo.ShortTimePattern; |
||||
|
case DateTimeFormat.LongTime: |
||||
|
return DateTimeFormatInfo.LongTimePattern; |
||||
|
case DateTimeFormat.FullDateTime: |
||||
|
return DateTimeFormatInfo.FullDateTimePattern; |
||||
|
case DateTimeFormat.MonthDay: |
||||
|
return DateTimeFormatInfo.MonthDayPattern; |
||||
|
case DateTimeFormat.RFC1123: |
||||
|
return DateTimeFormatInfo.RFC1123Pattern; |
||||
|
case DateTimeFormat.SortableDateTime: |
||||
|
return DateTimeFormatInfo.SortableDateTimePattern; |
||||
|
case DateTimeFormat.UniversalSortableDateTime: |
||||
|
return DateTimeFormatInfo.UniversalSortableDateTimePattern; |
||||
|
case DateTimeFormat.YearMonth: |
||||
|
return DateTimeFormatInfo.YearMonthPattern; |
||||
|
case DateTimeFormat.Custom: |
||||
|
return FormatString; |
||||
|
default: |
||||
|
throw new ArgumentException("Not a supported format"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void UpdateDateTime(int value) |
||||
|
{ |
||||
|
_fireSelectionChangedEvent = false; |
||||
|
DateTimeInfo info = _selectedDateTimeInfo; |
||||
|
|
||||
|
//this only occurs when the user manually type in a value for the Value Property
|
||||
|
if (info == null) |
||||
|
info = _dateTimeInfoList[0]; |
||||
|
|
||||
|
switch (info.Type) |
||||
|
{ |
||||
|
case DateTimePart.Year: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddYears(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.Month: |
||||
|
case DateTimePart.MonthName: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddMonths(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.Day: |
||||
|
case DateTimePart.DayName: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddDays(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.Hour12: |
||||
|
case DateTimePart.Hour24: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddHours(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.Minute: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddMinutes(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.Second: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddSeconds(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.Millisecond: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddMilliseconds(value); |
||||
|
break; |
||||
|
} |
||||
|
case DateTimePart.AmPmDesignator: |
||||
|
{ |
||||
|
Value = ((DateTime)Value).AddHours(value * 12); |
||||
|
break; |
||||
|
} |
||||
|
default: |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//we loose our selection when the Value is set so we need to reselect it without firing the selection changed event
|
||||
|
TextBox.Select(info.StartPosition, info.Length); |
||||
|
_fireSelectionChangedEvent = true; |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"> |
||||
|
|
||||
|
<coreConverters:InverseBoolConverter x:Key="InverseBoolConverter" /> |
||||
|
|
||||
|
<DataTemplate x:Key="DefaultWatermarkTemplate"> |
||||
|
<ContentControl Content="{Binding}" Foreground="Gray" Focusable="False" /> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- DateTimeUpDown --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:DateTimeUpDown}"> |
||||
|
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Right" /> |
||||
|
<Setter Property="TextAlignment" Value="Right" /> |
||||
|
<Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:DateTimeUpDown}"> |
||||
|
<local:ButtonSpinner x:Name="Spinner" IsTabStop="False" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
AllowSpin="{TemplateBinding AllowSpin}" ShowButtonSpinner="{TemplateBinding ShowButtonSpinner}"> |
||||
|
<local:WatermarkTextBox x:Name="TextBox" BorderThickness="0" |
||||
|
Background="{TemplateBinding Background}" |
||||
|
FontFamily="{TemplateBinding FontFamily}" |
||||
|
FontSize="{TemplateBinding FontSize}" |
||||
|
FontStretch="{TemplateBinding FontStretch}" |
||||
|
FontStyle="{TemplateBinding FontStyle}" |
||||
|
FontWeight="{TemplateBinding FontWeight}" |
||||
|
Foreground="{TemplateBinding Foreground}" |
||||
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
IsReadOnly="{Binding IsEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" |
||||
|
MinWidth="20" AcceptsReturn="False" |
||||
|
TextAlignment="{TemplateBinding TextAlignment}" |
||||
|
TextWrapping="NoWrap" |
||||
|
TabIndex="{TemplateBinding TabIndex}" |
||||
|
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Watermark="{TemplateBinding Watermark}" |
||||
|
WatermarkTemplate="{TemplateBinding WatermarkTemplate}"/> |
||||
|
</local:ButtonSpinner> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,24 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Mag.Converters |
||||
|
{ |
||||
|
internal class BorderThicknessToStrokeThicknessConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
Thickness thickness = (Thickness)value; |
||||
|
return (thickness.Bottom + thickness.Left + thickness.Right + thickness.Top) / 4; |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Data; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Mag.Converters |
||||
|
{ |
||||
|
internal class RadiusConverter : IValueConverter |
||||
|
{ |
||||
|
#region IValueConverter Members
|
||||
|
|
||||
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
return (double)value * 2; |
||||
|
} |
||||
|
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,166 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class Magnifier : Control |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
#region DefaultSize
|
||||
|
|
||||
|
internal Size DefaultSize |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new Size(2 * Radius, 2 * Radius); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //DefaultSize
|
||||
|
|
||||
|
#region MagnifierWidth
|
||||
|
|
||||
|
public static readonly DependencyProperty MagnifierWidthProperty = DependencyProperty.Register("MagnifierWidth", typeof(double), typeof(Magnifier), new UIPropertyMetadata(50.0)); |
||||
|
internal double MagnifierWidth |
||||
|
{ |
||||
|
get { return (double)GetValue(MagnifierWidthProperty); } |
||||
|
set { SetValue(MagnifierWidthProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //MagnifierWidth
|
||||
|
|
||||
|
#region MagnifierHeight
|
||||
|
|
||||
|
public static readonly DependencyProperty MagnifierHeightProperty = DependencyProperty.Register("MagnifierHeight", typeof(double), typeof(Magnifier), new UIPropertyMetadata(50.0)); |
||||
|
internal double MagnifierHeight |
||||
|
{ |
||||
|
get { return (double)GetValue(MagnifierHeightProperty); } |
||||
|
set { SetValue(MagnifierHeightProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //MagnifierWidth
|
||||
|
|
||||
|
#region Radius
|
||||
|
|
||||
|
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(50.0, new PropertyChangedCallback(OnRadiusPropertyChanged))); |
||||
|
public double Radius |
||||
|
{ |
||||
|
get { return (double)GetValue(RadiusProperty); } |
||||
|
set { SetValue(RadiusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnRadiusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Magnifier m = (Magnifier)d; |
||||
|
m.OnRadiusChanged(e); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnRadiusChanged(DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ResolveViewBox(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Radius
|
||||
|
|
||||
|
#region Target
|
||||
|
|
||||
|
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(UIElement), typeof(Magnifier)); |
||||
|
public UIElement Target |
||||
|
{ |
||||
|
get { return (UIElement)GetValue(TargetProperty); } |
||||
|
set { SetValue(TargetProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Target
|
||||
|
|
||||
|
#region ViewBox
|
||||
|
|
||||
|
public static readonly DependencyProperty ViewBoxProperty = DependencyProperty.Register("ViewBox", typeof(Rect), typeof(Magnifier), new FrameworkPropertyMetadata(default(Rect))); |
||||
|
internal Rect ViewBox |
||||
|
{ |
||||
|
get { return (Rect)GetValue(ViewBoxProperty); } |
||||
|
set { SetValue(ViewBoxProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //ViewBox
|
||||
|
|
||||
|
#region ZoomFactor
|
||||
|
|
||||
|
public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register("ZoomFactor", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(0.5, OnZoomFactorPropertyChanged, OnCoerceZoomFactorProperty)); |
||||
|
public double ZoomFactor |
||||
|
{ |
||||
|
get { return (double)GetValue(ZoomFactorProperty); } |
||||
|
set { SetValue(ZoomFactorProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnZoomFactorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
Magnifier m = (Magnifier)d; |
||||
|
m.OnZoomFactorChanged(e); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnZoomFactorChanged(DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
ResolveViewBox(); |
||||
|
} |
||||
|
|
||||
|
private static object OnCoerceZoomFactorProperty(DependencyObject d, object value) |
||||
|
{ |
||||
|
Magnifier m = (Magnifier)d; |
||||
|
return m.OnCoerceZoomFactor(value); |
||||
|
} |
||||
|
|
||||
|
protected virtual object OnCoerceZoomFactor(object value) |
||||
|
{ |
||||
|
double zoomFactor = (double)value; |
||||
|
|
||||
|
if (zoomFactor > 1) |
||||
|
zoomFactor = 1; |
||||
|
else if (zoomFactor < 0) |
||||
|
zoomFactor = 0; |
||||
|
|
||||
|
return zoomFactor; |
||||
|
} |
||||
|
|
||||
|
#endregion //ZoomFactor
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes static members of the <see cref="Magnifier"/> class.
|
||||
|
/// </summary>
|
||||
|
static Magnifier() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(Magnifier), new FrameworkPropertyMetadata(typeof(Magnifier))); |
||||
|
} |
||||
|
|
||||
|
public Magnifier() |
||||
|
{ |
||||
|
ResolveViewBox(); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void ResolveViewBox() |
||||
|
{ |
||||
|
double correction = (BorderThickness.Bottom + BorderThickness.Left + BorderThickness.Right + BorderThickness.Top == 0) ? 1 : 0; |
||||
|
|
||||
|
double width = DefaultSize.Width * ZoomFactor; |
||||
|
double height = DefaultSize.Height * ZoomFactor; |
||||
|
|
||||
|
MagnifierWidth = DefaultSize.Width - correction; |
||||
|
MagnifierHeight = DefaultSize.Height - correction; |
||||
|
|
||||
|
ViewBox = new Rect(ViewBox.Location, new Size(width, height)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
using System; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Media; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class MagnifierAdorner : Adorner |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private Magnifier _magnifier; |
||||
|
private Point _currentMousePosition; |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
public MagnifierAdorner(UIElement element, Magnifier magnifier) |
||||
|
: base(element) |
||||
|
{ |
||||
|
InputManager.Current.PostProcessInput += Current_PostProcessInput; |
||||
|
_magnifier = magnifier; |
||||
|
UpdateViewBox(); |
||||
|
AddVisualChild(_magnifier); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Private/Internal methods
|
||||
|
|
||||
|
private void Current_PostProcessInput(object sender, ProcessInputEventArgs e) |
||||
|
{ |
||||
|
Point pt = Mouse.GetPosition(this); |
||||
|
|
||||
|
if (_currentMousePosition == pt) |
||||
|
return; |
||||
|
|
||||
|
_currentMousePosition = pt; |
||||
|
UpdateViewBox(); |
||||
|
InvalidateArrange(); |
||||
|
} |
||||
|
|
||||
|
internal void UpdateViewBox() |
||||
|
{ |
||||
|
var viewBoxLocation = CalculateViewBoxLocation(); |
||||
|
_magnifier.ViewBox = new Rect(viewBoxLocation, _magnifier.ViewBox.Size); |
||||
|
} |
||||
|
|
||||
|
private Point CalculateViewBoxLocation() |
||||
|
{ |
||||
|
double offsetX = 0, offsetY = 0; |
||||
|
|
||||
|
Point adorner = Mouse.GetPosition(this); |
||||
|
Point element = Mouse.GetPosition(AdornedElement); |
||||
|
|
||||
|
offsetX = element.X - adorner.X; |
||||
|
offsetY = element.Y - adorner.Y; |
||||
|
|
||||
|
double left = _currentMousePosition.X - ((_magnifier.ViewBox.Width / 2) + offsetX); |
||||
|
double top = _currentMousePosition.Y - ((_magnifier.ViewBox.Height / 2) + offsetY); |
||||
|
return new Point(left, top); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Overrides
|
||||
|
|
||||
|
protected override Visual GetVisualChild(int index) |
||||
|
{ |
||||
|
return _magnifier; |
||||
|
} |
||||
|
|
||||
|
protected override int VisualChildrenCount |
||||
|
{ |
||||
|
get { return 1; } |
||||
|
} |
||||
|
|
||||
|
protected override Size MeasureOverride(Size constraint) |
||||
|
{ |
||||
|
_magnifier.Measure(constraint); |
||||
|
return base.MeasureOverride(constraint); |
||||
|
} |
||||
|
|
||||
|
protected override Size ArrangeOverride(Size finalSize) |
||||
|
{ |
||||
|
double x = _currentMousePosition.X - (_magnifier.DefaultSize.Width / 2); |
||||
|
double y = _currentMousePosition.Y - (_magnifier.DefaultSize.Height / 2); |
||||
|
_magnifier.Arrange(new Rect(x, y, _magnifier.DefaultSize.Width, _magnifier.DefaultSize.Height)); |
||||
|
return base.ArrangeOverride(finalSize); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,98 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Documents; |
||||
|
using System.Windows.Input; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class MagnifierManager : DependencyObject |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
private MagnifierAdorner _adorner; |
||||
|
private UIElement _element; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
public static readonly DependencyProperty CurrentProperty = DependencyProperty.RegisterAttached("Magnifier", typeof(Magnifier), typeof(UIElement), new FrameworkPropertyMetadata(null, OnMagnifierChanged)); |
||||
|
public static void SetMagnifier(UIElement element, Magnifier value) |
||||
|
{ |
||||
|
element.SetValue(CurrentProperty, value); |
||||
|
} |
||||
|
public static Magnifier GetMagnifier(UIElement element) |
||||
|
{ |
||||
|
return (Magnifier)element.GetValue(CurrentProperty); |
||||
|
} |
||||
|
|
||||
|
private static void OnMagnifierChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
UIElement target = d as UIElement; |
||||
|
|
||||
|
if (target == null) |
||||
|
throw new ArgumentException("Magnifier can only be attached to a UIElement."); |
||||
|
|
||||
|
MagnifierManager manager = new MagnifierManager(); |
||||
|
manager.AttachToMagnifier(target, e.NewValue as Magnifier); |
||||
|
} |
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void Element_MouseLeave(object sender, MouseEventArgs e) |
||||
|
{ |
||||
|
HideAdorner(); |
||||
|
} |
||||
|
|
||||
|
void Element_MouseEnter(object sender, MouseEventArgs e) |
||||
|
{ |
||||
|
ShowAdorner(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void AttachToMagnifier(UIElement element, Magnifier magnifier) |
||||
|
{ |
||||
|
_element = element; |
||||
|
_element.MouseEnter += Element_MouseEnter; |
||||
|
_element.MouseLeave += Element_MouseLeave; |
||||
|
|
||||
|
magnifier.Target = _element; |
||||
|
|
||||
|
_adorner = new MagnifierAdorner(_element, magnifier); |
||||
|
} |
||||
|
|
||||
|
void ShowAdorner() |
||||
|
{ |
||||
|
VerifyAdornerLayer(); |
||||
|
_adorner.Visibility = Visibility.Visible; |
||||
|
} |
||||
|
|
||||
|
bool VerifyAdornerLayer() |
||||
|
{ |
||||
|
if (_adorner.Parent != null) |
||||
|
return true; |
||||
|
|
||||
|
AdornerLayer layer = AdornerLayer.GetAdornerLayer(_element); |
||||
|
if (layer == null) |
||||
|
return false; |
||||
|
|
||||
|
layer.Add(_adorner); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
void HideAdorner() |
||||
|
{ |
||||
|
if (_adorner.Visibility == Visibility.Visible) |
||||
|
{ |
||||
|
_adorner.Visibility = Visibility.Collapsed; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:magConverters="clr-namespace:Microsoft.Windows.Controls.Mag.Converters"> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- Magnifier --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<magConverters:RadiusConverter x:Key="RadiusConverter"/> |
||||
|
<magConverters:BorderThicknessToStrokeThicknessConverter x:Key="BorderThicknessToStrokeThicknessConverter"/> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:Magnifier}"> |
||||
|
<Setter Property="IsHitTestVisible" Value="False"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:Magnifier}"> |
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="{Binding Path=Radius, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource RadiusConverter}}"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="{Binding Path=Radius, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource RadiusConverter}}"/> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Ellipse Width="{Binding Path=MagnifierWidth, RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding Path=MagnifierHeight, RelativeSource={RelativeSource TemplatedParent}}" Fill="{TemplateBinding Background}"/> |
||||
|
<Ellipse Stroke="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}}" StrokeThickness="{Binding Path=BorderThickness, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BorderThicknessToStrokeThicknessConverter}}"> |
||||
|
<Ellipse.Fill> |
||||
|
<VisualBrush Viewbox="{Binding Path=ViewBox, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
ViewboxUnits="Absolute" |
||||
|
Visual="{Binding Path=Target, RelativeSource={RelativeSource TemplatedParent}}"/> |
||||
|
</Ellipse.Fill> |
||||
|
</Ellipse> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,506 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Controls; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class MaskedTextBox : TextBox |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flags if the Text and Value properties are in the process of being sync'd
|
||||
|
/// </summary>
|
||||
|
private bool _isSyncingTextAndValueProperties; |
||||
|
private bool _isInitialized; |
||||
|
private bool _convertExceptionOccurred = false; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
protected MaskedTextProvider MaskProvider { get; set; } |
||||
|
|
||||
|
#region IncludePrompt
|
||||
|
|
||||
|
public static readonly DependencyProperty IncludePromptProperty = DependencyProperty.Register("IncludePrompt", typeof(bool), typeof(MaskedTextBox), new UIPropertyMetadata(false, OnIncludePromptPropertyChanged)); |
||||
|
public bool IncludePrompt |
||||
|
{ |
||||
|
get { return (bool)GetValue(IncludePromptProperty); } |
||||
|
set { SetValue(IncludePromptProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnIncludePromptPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox maskedTextBox = o as MaskedTextBox; |
||||
|
if (maskedTextBox != null) |
||||
|
maskedTextBox.OnIncludePromptChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnIncludePromptChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
ResolveMaskProvider(Mask); |
||||
|
} |
||||
|
|
||||
|
#endregion //IncludePrompt
|
||||
|
|
||||
|
#region IncludeLiterals
|
||||
|
|
||||
|
public static readonly DependencyProperty IncludeLiteralsProperty = DependencyProperty.Register("IncludeLiterals", typeof(bool), typeof(MaskedTextBox), new UIPropertyMetadata(true, OnIncludeLiteralsPropertyChanged)); |
||||
|
public bool IncludeLiterals |
||||
|
{ |
||||
|
get { return (bool)GetValue(IncludeLiteralsProperty); } |
||||
|
set { SetValue(IncludeLiteralsProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnIncludeLiteralsPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox maskedTextBox = o as MaskedTextBox; |
||||
|
if (maskedTextBox != null) |
||||
|
maskedTextBox.OnIncludeLiteralsChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnIncludeLiteralsChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
ResolveMaskProvider(Mask); |
||||
|
} |
||||
|
|
||||
|
#endregion //IncludeLiterals
|
||||
|
|
||||
|
#region Mask
|
||||
|
|
||||
|
public static readonly DependencyProperty MaskProperty = DependencyProperty.Register("Mask", typeof(string), typeof(MaskedTextBox), new UIPropertyMetadata(default(String), OnMaskPropertyChanged)); |
||||
|
public string Mask |
||||
|
{ |
||||
|
get { return (string)GetValue(MaskProperty); } |
||||
|
set { SetValue(MaskProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnMaskPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox maskedTextBox = o as MaskedTextBox; |
||||
|
if (maskedTextBox != null) |
||||
|
maskedTextBox.OnMaskChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnMaskChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
ResolveMaskProvider(newValue); |
||||
|
UpdateText(MaskProvider, 0); |
||||
|
} |
||||
|
|
||||
|
#endregion //Mask
|
||||
|
|
||||
|
#region PromptChar
|
||||
|
|
||||
|
public static readonly DependencyProperty PromptCharProperty = DependencyProperty.Register("PromptChar", typeof(char), typeof(MaskedTextBox), new UIPropertyMetadata('_', OnPromptCharChanged)); |
||||
|
public char PromptChar |
||||
|
{ |
||||
|
get { return (char)GetValue(PromptCharProperty); } |
||||
|
set { SetValue(PromptCharProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnPromptCharChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox maskedTextBox = o as MaskedTextBox; |
||||
|
if (maskedTextBox != null) |
||||
|
maskedTextBox.OnPromptCharChanged((char)e.OldValue, (char)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnPromptCharChanged(char oldValue, char newValue) |
||||
|
{ |
||||
|
ResolveMaskProvider(Mask); |
||||
|
} |
||||
|
|
||||
|
#endregion //PromptChar
|
||||
|
|
||||
|
#region SelectAllOnGotFocus
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectAllOnGotFocusProperty = DependencyProperty.Register("SelectAllOnGotFocus", typeof(bool), typeof(MaskedTextBox), new PropertyMetadata(false)); |
||||
|
public bool SelectAllOnGotFocus |
||||
|
{ |
||||
|
get { return (bool)GetValue(SelectAllOnGotFocusProperty); } |
||||
|
set { SetValue(SelectAllOnGotFocusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //SelectAllOnGotFocus
|
||||
|
|
||||
|
#region Text
|
||||
|
|
||||
|
private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox inputBase = o as MaskedTextBox; |
||||
|
if (inputBase != null) |
||||
|
inputBase.OnTextChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnTextChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
if (_isInitialized) |
||||
|
SyncTextAndValueProperties(MaskedTextBox.TextProperty, newValue); |
||||
|
} |
||||
|
|
||||
|
#endregion //Text
|
||||
|
|
||||
|
#region Value
|
||||
|
|
||||
|
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(MaskedTextBox), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValueChanged)); |
||||
|
public object Value |
||||
|
{ |
||||
|
get { return (object)GetValue(ValueProperty); } |
||||
|
set { SetValue(ValueProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox maskedTextBox = o as MaskedTextBox; |
||||
|
if (maskedTextBox != null) |
||||
|
maskedTextBox.OnValueChanged((object)e.OldValue, (object)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnValueChanged(object oldValue, object newValue) |
||||
|
{ |
||||
|
if (_isInitialized) |
||||
|
SyncTextAndValueProperties(DateTimeUpDown.ValueProperty, newValue); |
||||
|
|
||||
|
RoutedPropertyChangedEventArgs<object> args = new RoutedPropertyChangedEventArgs<object>(oldValue, newValue); |
||||
|
args.RoutedEvent = MaskedTextBox.ValueChangedEvent; |
||||
|
RaiseEvent(args); |
||||
|
} |
||||
|
|
||||
|
#endregion //Value
|
||||
|
|
||||
|
#region ValueType
|
||||
|
|
||||
|
public static readonly DependencyProperty ValueTypeProperty = DependencyProperty.Register("ValueType", typeof(Type), typeof(MaskedTextBox), new UIPropertyMetadata(typeof(String), OnValueTypeChanged)); |
||||
|
public Type ValueType |
||||
|
{ |
||||
|
get { return (Type)GetValue(ValueTypeProperty); } |
||||
|
set { SetValue(ValueTypeProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnValueTypeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MaskedTextBox maskedTextBox = o as MaskedTextBox; |
||||
|
if (maskedTextBox != null) |
||||
|
maskedTextBox.OnValueTypeChanged((Type)e.OldValue, (Type)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnValueTypeChanged(Type oldValue, Type newValue) |
||||
|
{ |
||||
|
if (_isInitialized) |
||||
|
SyncTextAndValueProperties(MaskedTextBox.TextProperty, Text); |
||||
|
} |
||||
|
|
||||
|
#endregion //ValueType
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static MaskedTextBox() |
||||
|
{ |
||||
|
TextProperty.OverrideMetadata(typeof(MaskedTextBox), new FrameworkPropertyMetadata(OnTextChanged)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
PreviewTextInput += TextBox_PreviewTextInput; |
||||
|
PreviewKeyDown += TextBox_PreviewKeyDown; |
||||
|
|
||||
|
CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, Paste)); //handle paste
|
||||
|
CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, null, CanCut)); //surpress cut
|
||||
|
|
||||
|
UpdateText(MaskProvider, 0); |
||||
|
} |
||||
|
|
||||
|
protected override void OnInitialized(EventArgs e) |
||||
|
{ |
||||
|
base.OnInitialized(e); |
||||
|
|
||||
|
if (!_isInitialized) |
||||
|
{ |
||||
|
_isInitialized = true; |
||||
|
SyncTextAndValueProperties(ValueProperty, Value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) |
||||
|
{ |
||||
|
if (SelectAllOnGotFocus) |
||||
|
SelectAll(); |
||||
|
|
||||
|
base.OnGotKeyboardFocus(e); |
||||
|
} |
||||
|
|
||||
|
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) |
||||
|
{ |
||||
|
if (!IsKeyboardFocused) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
Focus(); |
||||
|
} |
||||
|
|
||||
|
base.OnPreviewMouseLeftButtonDown(e); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) |
||||
|
{ |
||||
|
//if the text is readonly do not add the text
|
||||
|
if (IsReadOnly) |
||||
|
{ |
||||
|
e.Handled = true; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int position = SelectionStart; |
||||
|
MaskedTextProvider provider = MaskProvider; |
||||
|
|
||||
|
if (position < Text.Length) |
||||
|
{ |
||||
|
position = GetNextCharacterPosition(position); |
||||
|
|
||||
|
if (Keyboard.IsKeyToggled(Key.Insert)) |
||||
|
{ |
||||
|
if (provider.Replace(e.Text, position)) |
||||
|
position++; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (provider.InsertAt(e.Text, position)) |
||||
|
position++; |
||||
|
} |
||||
|
|
||||
|
position = GetNextCharacterPosition(position); |
||||
|
} |
||||
|
|
||||
|
UpdateText(provider, position); |
||||
|
e.Handled = true; |
||||
|
|
||||
|
base.OnPreviewTextInput(e); |
||||
|
} |
||||
|
|
||||
|
void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) |
||||
|
{ |
||||
|
if (IsReadOnly) |
||||
|
return; |
||||
|
|
||||
|
MaskedTextProvider provider = MaskProvider; |
||||
|
int position = SelectionStart; |
||||
|
int selectionlength = SelectionLength; |
||||
|
// If no selection use the start position else use end position
|
||||
|
int endposition = (selectionlength == 0) ? position : position + selectionlength - 1; |
||||
|
|
||||
|
if (e.Key == Key.Delete && position < Text.Length)//handle the delete key
|
||||
|
{ |
||||
|
if (provider.RemoveAt(position, endposition)) |
||||
|
UpdateText(provider, position); |
||||
|
|
||||
|
e.Handled = true; |
||||
|
} |
||||
|
else if (e.Key == Key.Space) |
||||
|
{ |
||||
|
if (provider.InsertAt(" ", position)) |
||||
|
UpdateText(provider, position); |
||||
|
e.Handled = true; |
||||
|
} |
||||
|
else if (e.Key == Key.Back)//handle the back space
|
||||
|
{ |
||||
|
if ((position > 0) && (selectionlength == 0)) |
||||
|
{ |
||||
|
position--; |
||||
|
if (provider.RemoveAt(position)) |
||||
|
UpdateText(provider, position); |
||||
|
} |
||||
|
|
||||
|
if (selectionlength != 0) |
||||
|
{ |
||||
|
if (provider.RemoveAt(position, endposition)) |
||||
|
{ |
||||
|
if (position > 0) |
||||
|
position--; |
||||
|
|
||||
|
UpdateText(provider, position); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
e.Handled = true; |
||||
|
} |
||||
|
|
||||
|
base.OnPreviewKeyDown(e); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Events
|
||||
|
|
||||
|
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<object>), typeof(MaskedTextBox)); |
||||
|
public event RoutedPropertyChangedEventHandler<object> ValueChanged |
||||
|
{ |
||||
|
add { AddHandler(ValueChangedEvent, value); } |
||||
|
remove { RemoveHandler(ValueChangedEvent, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Events
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
#region Private
|
||||
|
|
||||
|
private void UpdateText(MaskedTextProvider provider, int position) |
||||
|
{ |
||||
|
if (provider == null) |
||||
|
throw new ArgumentNullException("MaskedTextProvider", "Mask cannot be null."); |
||||
|
|
||||
|
Text = provider.ToDisplayString(); |
||||
|
|
||||
|
SelectionStart = position; |
||||
|
} |
||||
|
|
||||
|
private int GetNextCharacterPosition(int startPosition) |
||||
|
{ |
||||
|
int position = MaskProvider.FindEditPositionFrom(startPosition, true); |
||||
|
return position == -1 ? startPosition : position; |
||||
|
} |
||||
|
|
||||
|
private void ResolveMaskProvider(string mask) |
||||
|
{ |
||||
|
//do not create a mask provider if the Mask is empty, which can occur if the IncludePrompt and IncludeLiterals properties
|
||||
|
//are set prior to the Mask.
|
||||
|
if (String.IsNullOrEmpty(mask)) |
||||
|
return; |
||||
|
|
||||
|
MaskProvider = new MaskedTextProvider(mask) |
||||
|
{ |
||||
|
IncludePrompt = this.IncludePrompt, |
||||
|
IncludeLiterals = this.IncludeLiterals, |
||||
|
PromptChar = this.PromptChar |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private object ConvertTextToValue(string text) |
||||
|
{ |
||||
|
object convertedValue = null; |
||||
|
|
||||
|
Type dataType = ValueType; |
||||
|
|
||||
|
string valueToConvert = MaskProvider.ToString().Trim(); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
if (valueToConvert.GetType() == dataType || dataType.IsInstanceOfType(valueToConvert)) |
||||
|
{ |
||||
|
convertedValue = valueToConvert; |
||||
|
} |
||||
|
#if !VS2008
|
||||
|
else if (String.IsNullOrWhiteSpace(valueToConvert)) |
||||
|
{ |
||||
|
convertedValue = Activator.CreateInstance(dataType); |
||||
|
} |
||||
|
#else
|
||||
|
else if (String.IsNullOrEmpty(valueToConvert)) |
||||
|
{ |
||||
|
convertedValue = Activator.CreateInstance(dataType); |
||||
|
} |
||||
|
#endif
|
||||
|
else if (null == convertedValue && valueToConvert is IConvertible) |
||||
|
{ |
||||
|
convertedValue = Convert.ChangeType(valueToConvert, dataType); |
||||
|
} |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
//if an excpetion occurs revert back to original value
|
||||
|
_convertExceptionOccurred = true; |
||||
|
return Value; |
||||
|
} |
||||
|
|
||||
|
return convertedValue; |
||||
|
} |
||||
|
|
||||
|
private string ConvertValueToText(object value) |
||||
|
{ |
||||
|
if (value == null) |
||||
|
value = string.Empty; |
||||
|
|
||||
|
if (_convertExceptionOccurred) |
||||
|
{ |
||||
|
value = Value; |
||||
|
_convertExceptionOccurred = false; |
||||
|
} |
||||
|
|
||||
|
//I have only seen this occur while in Blend, but we need it here so the Blend designer doesn't crash.
|
||||
|
if (MaskProvider == null) |
||||
|
return value.ToString(); |
||||
|
|
||||
|
MaskProvider.Set(value.ToString()); |
||||
|
return MaskProvider.ToDisplayString(); |
||||
|
} |
||||
|
|
||||
|
private void SyncTextAndValueProperties(DependencyProperty p, object newValue) |
||||
|
{ |
||||
|
//prevents recursive syncing properties
|
||||
|
if (_isSyncingTextAndValueProperties) |
||||
|
return; |
||||
|
|
||||
|
_isSyncingTextAndValueProperties = true; |
||||
|
|
||||
|
//this only occures when the user typed in the value
|
||||
|
if (MaskedTextBox.TextProperty == p) |
||||
|
{ |
||||
|
if (newValue != null) |
||||
|
SetValue(MaskedTextBox.ValueProperty, ConvertTextToValue(newValue.ToString())); |
||||
|
} |
||||
|
|
||||
|
SetValue(MaskedTextBox.TextProperty, ConvertValueToText(newValue)); |
||||
|
|
||||
|
_isSyncingTextAndValueProperties = false; |
||||
|
} |
||||
|
|
||||
|
#endregion //Private
|
||||
|
|
||||
|
#endregion //Methods
|
||||
|
|
||||
|
#region Commands
|
||||
|
|
||||
|
private void Paste(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
if (IsReadOnly) |
||||
|
return; |
||||
|
|
||||
|
MaskedTextProvider provider = MaskProvider; |
||||
|
int position = SelectionStart; |
||||
|
|
||||
|
object data = Clipboard.GetData(DataFormats.Text); |
||||
|
if (data != null) |
||||
|
{ |
||||
|
string text = data.ToString().Trim(); |
||||
|
if (text.Length > 0) |
||||
|
{ |
||||
|
provider.Set(text); |
||||
|
UpdateText(provider, position); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void CanCut(object sender, CanExecuteRoutedEventArgs e) |
||||
|
{ |
||||
|
e.CanExecute = false; |
||||
|
e.Handled = true; |
||||
|
} |
||||
|
|
||||
|
#endregion //Commands
|
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,517 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Media; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
[TemplateVisualState(Name = VisualStates.OK, GroupName = VisualStates.MessageBoxButtonsGroup)] |
||||
|
[TemplateVisualState(Name = VisualStates.OKCancel, GroupName = VisualStates.MessageBoxButtonsGroup)] |
||||
|
[TemplateVisualState(Name = VisualStates.YesNo, GroupName = VisualStates.MessageBoxButtonsGroup)] |
||||
|
[TemplateVisualState(Name = VisualStates.YesNoCancel, GroupName = VisualStates.MessageBoxButtonsGroup)] |
||||
|
public class MessageBox : Control |
||||
|
{ |
||||
|
#region Private Members
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tracks the MessageBoxButon value passed into the InitializeContainer method
|
||||
|
/// </summary>
|
||||
|
private MessageBoxButton _button = MessageBoxButton.OK; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tracks the MessageBoxResult to set as the default and focused button
|
||||
|
/// </summary>
|
||||
|
private MessageBoxResult _defaultResult = MessageBoxResult.None; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tracks the owner of the MessageBox
|
||||
|
/// </summary>
|
||||
|
private Window _owner; |
||||
|
|
||||
|
#endregion //Private Members
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static MessageBox() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageBox), new FrameworkPropertyMetadata(typeof(MessageBox))); |
||||
|
} |
||||
|
|
||||
|
internal MessageBox() |
||||
|
{ /*user cannot create instance */ } |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region Protected Properties
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A System.Windows.MessageBoxResult value that specifies which message box button was clicked by the user.
|
||||
|
/// </summary>
|
||||
|
protected MessageBoxResult MessageBoxResult = MessageBoxResult.None; |
||||
|
|
||||
|
protected Window Container { get; private set; } |
||||
|
protected Thumb DragWidget { get; private set; } |
||||
|
|
||||
|
#endregion //Protected Properties
|
||||
|
|
||||
|
#region Dependency Properties
|
||||
|
|
||||
|
public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register("Caption", typeof(string), typeof(MessageBox), new UIPropertyMetadata(String.Empty)); |
||||
|
public string Caption |
||||
|
{ |
||||
|
get { return (string)GetValue(CaptionProperty); } |
||||
|
set { SetValue(CaptionProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty CaptionForegroundProperty = DependencyProperty.Register("CaptionForeground", typeof(Brush), typeof(MessageBox), new UIPropertyMetadata(null)); |
||||
|
public Brush CaptionForeground |
||||
|
{ |
||||
|
get { return (Brush)GetValue(CaptionForegroundProperty); } |
||||
|
set { SetValue(CaptionForegroundProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty CloseButtonStyleProperty = DependencyProperty.Register("CloseButtonStyle", typeof(Style), typeof(MessageBox), new PropertyMetadata(null)); |
||||
|
public Style CloseButtonStyle |
||||
|
{ |
||||
|
get { return (Style)GetValue(CloseButtonStyleProperty); } |
||||
|
set { SetValue(CloseButtonStyleProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(MessageBox), new UIPropertyMetadata(default(ImageSource))); |
||||
|
public ImageSource ImageSource |
||||
|
{ |
||||
|
get { return (ImageSource)GetValue(ImageSourceProperty); } |
||||
|
set { SetValue(ImageSourceProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MessageBox), new UIPropertyMetadata(String.Empty)); |
||||
|
public string Text |
||||
|
{ |
||||
|
get { return (string)GetValue(TextProperty); } |
||||
|
set { SetValue(TextProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty WindowBackgroundProperty = DependencyProperty.Register("WindowBackground", typeof(Brush), typeof(MessageBox), new PropertyMetadata(null)); |
||||
|
public Brush WindowBackground |
||||
|
{ |
||||
|
get { return (Brush)GetValue(WindowBackgroundProperty); } |
||||
|
set { SetValue(WindowBackgroundProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty WindowBorderBrushProperty = DependencyProperty.Register("WindowBorderBrush", typeof(Brush), typeof(MessageBox), new PropertyMetadata(null)); |
||||
|
public Brush WindowBorderBrush |
||||
|
{ |
||||
|
get { return (Brush)GetValue(WindowBorderBrushProperty); } |
||||
|
set { SetValue(WindowBorderBrushProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public static readonly DependencyProperty WindowOpacityProperty = DependencyProperty.Register("WindowOpacity", typeof(double), typeof(MessageBox), new PropertyMetadata(null)); |
||||
|
public double WindowOpacity |
||||
|
{ |
||||
|
get { return (double)GetValue(WindowOpacityProperty); } |
||||
|
set { SetValue(WindowOpacityProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //Dependency Properties
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the OnApplyTemplate method.
|
||||
|
/// </summary>
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
DragWidget = GetTemplateChild("PART_DragWidget") as Thumb; |
||||
|
if (DragWidget != null) |
||||
|
DragWidget.DragDelta += (o, e) => ProcessMove(e); |
||||
|
|
||||
|
AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Button_Click)); |
||||
|
|
||||
|
ChangeVisualState(_button.ToString(), true); |
||||
|
|
||||
|
SetDefaultResult(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
#region Public Static
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Displays a message box that has a message and that returns a result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageText">A System.String that specifies the text to display.</param>
|
||||
|
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
|
public static MessageBoxResult Show(string messageText) |
||||
|
{ |
||||
|
return Show(messageText, string.Empty, MessageBoxButton.OK); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Displays a message box that has a message and that returns a result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="owner">A System.Windows.Window that represents the owner of the MessageBox</param>
|
||||
|
/// <param name="messageText">A System.String that specifies the text to display.</param>
|
||||
|
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
|
public static MessageBoxResult Show(Window owner, string messageText) |
||||
|
{ |
||||
|
return Show(owner, messageText, string.Empty, MessageBoxButton.OK); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Displays a message box that has a message and title bar caption; and that returns a result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageText">A System.String that specifies the text to display.</param>
|
||||
|
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
|
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
|
public static MessageBoxResult Show(string messageText, string caption) |
||||
|
{ |
||||
|
return Show(messageText, caption, MessageBoxButton.OK); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static MessageBoxResult Show(Window owner, string messageText, string caption) |
||||
|
{ |
||||
|
return Show(owner, messageText, caption, MessageBoxButton.OK); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Displays a message box that has a message and that returns a result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageText">A System.String that specifies the text to display.</param>
|
||||
|
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
|
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
|
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
|
public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button) |
||||
|
{ |
||||
|
return ShowCore(null, messageText, caption, button, MessageBoxImage.None, MessageBoxResult.None); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button) |
||||
|
{ |
||||
|
return ShowCore(owner, messageText, caption, button, MessageBoxImage.None, MessageBoxResult.None); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Displays a message box that has a message and that returns a result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageText">A System.String that specifies the text to display.</param>
|
||||
|
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
|
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
|
/// <param name="image"> A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
|
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
|
public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon) |
||||
|
{ |
||||
|
return ShowCore(null, messageText, caption, button, icon, MessageBoxResult.None); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon) |
||||
|
{ |
||||
|
return ShowCore(owner, messageText, caption, button, icon, MessageBoxResult.None); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Displays a message box that has a message and that returns a result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageText">A System.String that specifies the text to display.</param>
|
||||
|
/// <param name="caption">A System.String that specifies the title bar caption to display.</param>
|
||||
|
/// <param name="button">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
|
||||
|
/// <param name="image"> A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
|
||||
|
/// <param name="defaultResult">A System.Windows.MessageBoxResult value that specifies the default result of the MessageBox.</param>
|
||||
|
/// <returns>A System.Windows.MessageBoxResult value that specifies which message box button is clicked by the user.</returns>
|
||||
|
public static MessageBoxResult Show(string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) |
||||
|
{ |
||||
|
return ShowCore(null, messageText, caption, button, icon, defaultResult); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static MessageBoxResult Show(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) |
||||
|
{ |
||||
|
return ShowCore(owner, messageText, caption, button, icon, defaultResult); |
||||
|
} |
||||
|
|
||||
|
#endregion //Public Static
|
||||
|
|
||||
|
#region Protected
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Shows the container which contains the MessageBox.
|
||||
|
/// </summary>
|
||||
|
protected void Show() |
||||
|
{ |
||||
|
Container.ShowDialog(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes the MessageBox.
|
||||
|
/// </summary>
|
||||
|
/// <param name="text">The text.</param>
|
||||
|
/// <param name="caption">The caption.</param>
|
||||
|
/// <param name="button">The button.</param>
|
||||
|
/// <param name="image">The image.</param>
|
||||
|
protected void InitializeMessageBox(Window owner, string text, string caption, MessageBoxButton button, MessageBoxImage image, MessageBoxResult defaultResult) |
||||
|
{ |
||||
|
Text = text; |
||||
|
Caption = caption; |
||||
|
_button = button; |
||||
|
_defaultResult = defaultResult; |
||||
|
_owner = owner; |
||||
|
SetImageSource(image); |
||||
|
Container = CreateContainer(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Changes the control's visual state(s).
|
||||
|
/// </summary>
|
||||
|
/// <param name="name">name of the state</param>
|
||||
|
/// <param name="useTransitions">True if state transitions should be used.</param>
|
||||
|
protected void ChangeVisualState(string name, bool useTransitions) |
||||
|
{ |
||||
|
VisualStateManager.GoToState(this, name, useTransitions); |
||||
|
} |
||||
|
|
||||
|
#endregion //Protected
|
||||
|
|
||||
|
#region Private
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the button that represents the _defaultResult to the default button and gives it focus.
|
||||
|
/// </summary>
|
||||
|
private void SetDefaultResult() |
||||
|
{ |
||||
|
var defaultButton = GetDefaultButtonFromDefaultResult(); |
||||
|
if (defaultButton != null) |
||||
|
{ |
||||
|
defaultButton.IsDefault = true; |
||||
|
defaultButton.Focus(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the default button from the _defaultResult.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The default button that represents the defaultResult</returns>
|
||||
|
private Button GetDefaultButtonFromDefaultResult() |
||||
|
{ |
||||
|
Button defaultButton = null; |
||||
|
switch (_defaultResult) |
||||
|
{ |
||||
|
case MessageBoxResult.Cancel: |
||||
|
defaultButton = GetMessageBoxButton("PART_CancelButton"); |
||||
|
break; |
||||
|
case MessageBoxResult.No: |
||||
|
defaultButton = GetMessageBoxButton("PART_NoButton"); |
||||
|
break; |
||||
|
case MessageBoxResult.OK: |
||||
|
defaultButton = GetMessageBoxButton("PART_OkButton"); |
||||
|
break; |
||||
|
case MessageBoxResult.Yes: |
||||
|
defaultButton = GetMessageBoxButton("PART_YesButton"); |
||||
|
break; |
||||
|
case MessageBoxResult.None: |
||||
|
defaultButton = GetDefaultButton(); |
||||
|
break; |
||||
|
} |
||||
|
return defaultButton; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the default button.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>Used when the _defaultResult is set to None</remarks>
|
||||
|
/// <returns>The button to use as the default</returns>
|
||||
|
private Button GetDefaultButton() |
||||
|
{ |
||||
|
Button defaultButton = null; |
||||
|
switch (_button) |
||||
|
{ |
||||
|
case MessageBoxButton.OK: |
||||
|
case MessageBoxButton.OKCancel: |
||||
|
defaultButton = GetMessageBoxButton("PART_OkButton"); |
||||
|
break; |
||||
|
case MessageBoxButton.YesNo: |
||||
|
case MessageBoxButton.YesNoCancel: |
||||
|
defaultButton = GetMessageBoxButton("PART_YesButton"); |
||||
|
break; |
||||
|
} |
||||
|
return defaultButton; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a message box button.
|
||||
|
/// </summary>
|
||||
|
/// <param name="name">The name of the button to get.</param>
|
||||
|
/// <returns>The button</returns>
|
||||
|
private Button GetMessageBoxButton(string name) |
||||
|
{ |
||||
|
Button button = GetTemplateChild(name) as Button; |
||||
|
return button; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Shows the MessageBox.
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageText">The message text.</param>
|
||||
|
/// <param name="caption">The caption.</param>
|
||||
|
/// <param name="button">The button.</param>
|
||||
|
/// <param name="icon">The icon.</param>
|
||||
|
/// <param name="defaultResult">The default result.</param>
|
||||
|
/// <returns></returns>
|
||||
|
private static MessageBoxResult ShowCore(Window owner, string messageText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult) |
||||
|
{ |
||||
|
MessageBox msgBox = new MessageBox(); |
||||
|
msgBox.InitializeMessageBox(owner, messageText, caption, button, icon, defaultResult); |
||||
|
msgBox.Show(); |
||||
|
return msgBox.MessageBoxResult; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Resolves the owner Window of the MessageBox.
|
||||
|
/// </summary>
|
||||
|
/// <returns>the owner Window</returns>
|
||||
|
private static Window ResolveOwnerWindow() |
||||
|
{ |
||||
|
Window owner = null; |
||||
|
if (Application.Current != null) |
||||
|
{ |
||||
|
foreach (Window w in Application.Current.Windows) |
||||
|
{ |
||||
|
if (w.IsActive) |
||||
|
{ |
||||
|
owner = w; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return owner; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the message image source.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">The image to show.</param>
|
||||
|
private void SetImageSource(MessageBoxImage image) |
||||
|
{ |
||||
|
String iconName = String.Empty; |
||||
|
|
||||
|
switch (image) |
||||
|
{ |
||||
|
case MessageBoxImage.Error: |
||||
|
{ |
||||
|
iconName = "Error48.png"; |
||||
|
break; |
||||
|
} |
||||
|
case MessageBoxImage.Information: |
||||
|
{ |
||||
|
iconName = "Information48.png"; |
||||
|
break; |
||||
|
} |
||||
|
case MessageBoxImage.Question: |
||||
|
{ |
||||
|
iconName = "Question48.png"; |
||||
|
break; |
||||
|
} |
||||
|
case MessageBoxImage.Warning: |
||||
|
{ |
||||
|
iconName = "Warning48.png"; |
||||
|
break; |
||||
|
} |
||||
|
case MessageBoxImage.None: |
||||
|
default: |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
ImageSource = (ImageSource)new ImageSourceConverter().ConvertFromString(String.Format("pack://application:,,,/WPFToolkit.Extended;component/MessageBox/Icons/{0}", iconName)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates the container which will host the MessageBox control.
|
||||
|
/// </summary>
|
||||
|
/// <returns></returns>
|
||||
|
private Window CreateContainer() |
||||
|
{ |
||||
|
var newWindow = new Window(); |
||||
|
newWindow.AllowsTransparency = true; |
||||
|
newWindow.Background = Brushes.Transparent; |
||||
|
newWindow.Content = this; |
||||
|
newWindow.Owner = _owner ?? ResolveOwnerWindow(); |
||||
|
|
||||
|
if (newWindow.Owner != null) |
||||
|
newWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; |
||||
|
else |
||||
|
newWindow.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; |
||||
|
|
||||
|
newWindow.ShowInTaskbar = false; |
||||
|
newWindow.SizeToContent = System.Windows.SizeToContent.WidthAndHeight; |
||||
|
newWindow.ResizeMode = System.Windows.ResizeMode.NoResize; |
||||
|
newWindow.WindowStyle = System.Windows.WindowStyle.None; |
||||
|
return newWindow; |
||||
|
} |
||||
|
|
||||
|
#endregion //Private
|
||||
|
|
||||
|
#endregion //Methods
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Processes the move of a drag operation on the header.
|
||||
|
/// </summary>
|
||||
|
/// <param name="e">The <see cref="System.Windows.Controls.Primitives.DragDeltaEventArgs"/> instance containing the event data.</param>
|
||||
|
private void ProcessMove(DragDeltaEventArgs e) |
||||
|
{ |
||||
|
Container.Left = Container.Left + e.HorizontalChange; |
||||
|
Container.Top = Container.Top + e.VerticalChange; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Sets the MessageBoxResult according to the button pressed and then closes the MessageBox.
|
||||
|
/// </summary>
|
||||
|
/// <param name="sender">The source of the event.</param>
|
||||
|
/// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
|
||||
|
private void Button_Click(object sender, RoutedEventArgs e) |
||||
|
{ |
||||
|
Button button = e.OriginalSource as Button; |
||||
|
switch (button.Name) |
||||
|
{ |
||||
|
case "PART_NoButton": |
||||
|
MessageBoxResult = MessageBoxResult.No; |
||||
|
break; |
||||
|
case "PART_YesButton": |
||||
|
MessageBoxResult = MessageBoxResult.Yes; |
||||
|
break; |
||||
|
case "PART_CloseButton": |
||||
|
case "PART_CancelButton": |
||||
|
MessageBoxResult = MessageBoxResult.Cancel; |
||||
|
break; |
||||
|
case "PART_OkButton": |
||||
|
MessageBoxResult = MessageBoxResult.OK; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
Close(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Closes the MessageBox.
|
||||
|
/// </summary>
|
||||
|
private void Close() |
||||
|
{ |
||||
|
Container.Close(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
internal static partial class VisualStates |
||||
|
{ |
||||
|
public const string MessageBoxButtonsGroup = "MessageBoxButtonsGroup"; |
||||
|
|
||||
|
public const string OK = "OK"; |
||||
|
|
||||
|
public const string OKCancel = "OKCancel"; |
||||
|
|
||||
|
public const string YesNo = "YesNo"; |
||||
|
|
||||
|
public const string YesNoCancel = "YesNoCancel"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,299 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls"> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="WindowDarkBrush" 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="WindowBackgroundBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFffffff"/> |
||||
|
<GradientStop Offset="0.479" Color="#FFf4f5f6"/> |
||||
|
<GradientStop Offset="1" Color="#FFd0d6db"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="WindowButtonHoverBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFb5bdc8"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF8399a9"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF718597"/> |
||||
|
<GradientStop Offset="0.906" Color="#FFb9c1ca"/> |
||||
|
<GradientStop Offset="1" Color="#FFb9c1ca"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="WindowButtonPressedBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FF6b7c8d"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF4d606f"/> |
||||
|
<GradientStop Offset="0.370" Color="#FF465460"/> |
||||
|
<GradientStop Offset="0.906" Color="#FF262d33"/> |
||||
|
<GradientStop Offset="1" Color="#FF262d33"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<Style x:Key="WindowCloseButtonStyle" TargetType="Button"> |
||||
|
<Setter Property="Foreground" Value="#FF000000"/> |
||||
|
<Setter Property="Padding" Value="3"/> |
||||
|
<Setter Property="BorderThickness" Value="1"/> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="Button"> |
||||
|
<Grid> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="CommonStates"> |
||||
|
<VisualState x:Name="Normal"/> |
||||
|
<VisualState x:Name="MouseOver"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource WindowButtonHoverBrush}"></DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="Pressed"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background)"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource WindowButtonPressedBrush}"></DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
<Border x:Name="Background" CornerRadius="0,0,2,0" Background="{StaticResource WindowDarkBrush}"> |
||||
|
<Border Margin="1,0,1,1" BorderBrush="#59FFFFFF" BorderThickness="1" CornerRadius="0,0,1,0"/> |
||||
|
</Border> |
||||
|
<ContentPresenter x:Name="contentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> |
||||
|
<Path x:Name="path" |
||||
|
Height="6" |
||||
|
Width="7" |
||||
|
Stretch="Fill" |
||||
|
Opacity="1" |
||||
|
Data="M 2,6 C2,6 3,6 3,6 3,6 3,5 3,5 3,5 4,5 4,5 4,5 4,6 4,6 4,6 5,6 5,6 5,6 7,6 7,6 7,6 7,5 7,5 7,5 6,5 6,5 6,5 6,4 6,4 6,4 5,4 5,4 5,4 5,2 5,2 5,2 6,2 6,2 6,2 6,1 6,1 6,1 7,1 7,1 7,1 7,0 7,0 7,0 5,0 5,0 5,0 4,0 4,0 4,0 4,1 4,1 4,1 3,1 3,1 3,1 3,0 3,0 3,0 2,0 2,0 2,0 0,0 0,0 0,0 0,1 0,1 0,1 1,1 1,1 1,1 1,2 1,2 1,2 2,2 2,2 2,2 2,4 2,4 2,4 1,4 1,4 1,4 1,5 1,5 1,5 0,5 0,5 0,5 0,6 0,6 0,6 2,6 2,6 z" |
||||
|
Fill="White" Margin="0,0,0,1" Visibility="Collapsed" /> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- MessageBox --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<ControlTemplate x:Key="MessageBoxDragWidgetTemplate" TargetType="{x:Type Thumb}"> |
||||
|
<Border Background="Transparent"> |
||||
|
</Border> |
||||
|
</ControlTemplate> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:MessageBox}"> |
||||
|
<Setter Property="Background" Value="#FFFFFFFF"/> |
||||
|
<Setter Property="BorderBrush" Value="{StaticResource WindowDarkBrush}" /> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="CaptionForeground" Value="#FF000000" /> |
||||
|
<Setter Property="CloseButtonStyle" Value="{StaticResource WindowCloseButtonStyle}" /> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="HorizontalAlignment" Value="Left" /> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Left" /> |
||||
|
<Setter Property="IsEnabled" Value="true" /> |
||||
|
<Setter Property="MinWidth" Value="350" /> |
||||
|
<Setter Property="MinHeight" Value="50" /> |
||||
|
<Setter Property="MaxHeight" Value="250" /> |
||||
|
<Setter Property="VerticalAlignment" Value="Top" /> |
||||
|
<Setter Property="VerticalContentAlignment" Value="Top" /> |
||||
|
<Setter Property="WindowBorderBrush" Value="{StaticResource WindowDarkBrush}" /> |
||||
|
<Setter Property="WindowBackground" Value="{StaticResource WindowBackgroundBrush}" /> |
||||
|
<Setter Property="WindowOpacity" Value="1.0" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:MessageBox}"> |
||||
|
<Grid x:Name="Root"> |
||||
|
<VisualStateManager.VisualStateGroups> |
||||
|
<VisualStateGroup x:Name="group1"> |
||||
|
<VisualState x:Name="OK"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_OkButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="OKCancel"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_OkButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_CancelButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
<VisualState x:Name="YesNo"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_YesButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_NoButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
|
||||
|
<VisualState x:Name="YesNoCancel"> |
||||
|
<Storyboard> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_YesButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_NoButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_CancelButton" Storyboard.TargetProperty="Visibility"> |
||||
|
<DiscreteObjectKeyFrame KeyTime="0"> |
||||
|
<DiscreteObjectKeyFrame.Value> |
||||
|
<Visibility>Visible</Visibility> |
||||
|
</DiscreteObjectKeyFrame.Value> |
||||
|
</DiscreteObjectKeyFrame> |
||||
|
</ObjectAnimationUsingKeyFrames> |
||||
|
</Storyboard> |
||||
|
</VisualState> |
||||
|
</VisualStateGroup> |
||||
|
</VisualStateManager.VisualStateGroups> |
||||
|
|
||||
|
<!-- Borders --> |
||||
|
<Grid x:Name="MessageBoxWindowGrid"> |
||||
|
<Border BorderBrush="{TemplateBinding WindowBorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5,5,0,0" Opacity="{TemplateBinding WindowOpacity}"/> |
||||
|
<Grid Margin="0" Background="{x:Null}"> |
||||
|
<Border x:Name="MessageBoxWindow" Margin="1,1,1,1" Background="{TemplateBinding WindowBackground}" CornerRadius="4,4,0,0" Opacity="{TemplateBinding WindowOpacity}"/> |
||||
|
<Border BorderBrush="White" BorderThickness="1" CornerRadius="4,4,0,0" Margin="1" Opacity="0.7"/> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition Height="Auto" MinHeight="26"/> |
||||
|
<RowDefinition /> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<!-- Content Border --> |
||||
|
<Grid Margin="6,0,6,6" x:Name="ContentGrid" Grid.Row="1"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition/> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
<Border BorderBrush="#FFFFFFFF" BorderThickness="1" CornerRadius="1"/> |
||||
|
<Border Margin="1" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0.1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"> |
||||
|
|
||||
|
<Grid MinWidth="350"> |
||||
|
<Grid.RowDefinitions> |
||||
|
<RowDefinition /> |
||||
|
<RowDefinition Height="Auto" /> |
||||
|
</Grid.RowDefinitions> |
||||
|
|
||||
|
<Grid Margin="24,16,24,22"> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
<ColumnDefinition Width="*"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<!-- Message Image --> |
||||
|
<Image x:Name="MessageBoxImage" VerticalAlignment="Top" SnapsToDevicePixels="True" Stretch="None" Margin="-6,-1,10,-4" Source="{TemplateBinding ImageSource}"></Image> |
||||
|
|
||||
|
<!-- Message Text --> |
||||
|
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto"> |
||||
|
<TextBlock x:Name="MessageText" TextWrapping="Wrap" VerticalAlignment="Center" MaxWidth="450" |
||||
|
Text="{TemplateBinding Text}" |
||||
|
FontFamily="{TemplateBinding FontFamily}" |
||||
|
FontSize="{TemplateBinding FontSize}" |
||||
|
FontStyle="{TemplateBinding FontStyle}" |
||||
|
FontWeight="{TemplateBinding FontWeight}" |
||||
|
Foreground="{TemplateBinding Foreground}"/> |
||||
|
</ScrollViewer> |
||||
|
|
||||
|
</Grid> |
||||
|
|
||||
|
<!-- Buttons --> |
||||
|
<Grid Grid.Row="1" HorizontalAlignment="Right" Margin="12,0,12,12"> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
<Button Grid.Column="0" x:Name="PART_YesButton" MinWidth="65" Margin="6,0,0,0" Visibility="Collapsed">Yes</Button> |
||||
|
<Button Grid.Column="1" x:Name="PART_NoButton" MinWidth="65" Margin="6,0,0,0" Visibility="Collapsed">No</Button> |
||||
|
<Button Grid.Column="2" x:Name="PART_OkButton" MinWidth="65" Margin="6,0,0,0" Visibility="Collapsed">OK</Button> |
||||
|
<Button Grid.Column="3" x:Name="PART_CancelButton" MinWidth="65" Margin="6,0,0,0" Visibility="Collapsed">Cancel</Button> |
||||
|
</Grid> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
|
||||
|
<!-- Header --> |
||||
|
<Border x:Name="HeaderArea" Background="Transparent" Grid.Column="1" CornerRadius="5,5,0,0" Margin="1,1,1,0"> |
||||
|
<Grid> |
||||
|
<Grid x:Name="CaptionHeader" Margin="1,1,105,0" VerticalAlignment="Center"> |
||||
|
<!-- Caption --> |
||||
|
<ContentControl x:Name="Caption" Margin="5,0,0,0" IsTabStop="False" HorizontalAlignment="Stretch" |
||||
|
Content="{TemplateBinding Caption}" |
||||
|
Foreground="{TemplateBinding CaptionForeground}"/> |
||||
|
|
||||
|
</Grid> |
||||
|
<Thumb x:Name="PART_DragWidget" Template="{StaticResource MessageBoxDragWidgetTemplate}" IsTabStop="False" /> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
|
||||
|
</Grid> |
||||
|
|
||||
|
<Border x:Name="Resize" BorderThickness="7" BorderBrush="Transparent" /> |
||||
|
|
||||
|
<!-- Close Button --> |
||||
|
<Border BorderBrush="#A5FFFFFF" BorderThickness="1,0,1,1" CornerRadius="0,0,3,3" VerticalAlignment="Top" Margin="0,1,7,0" HorizontalAlignment="Right"> |
||||
|
<Button x:Name="PART_CloseButton" Style="{TemplateBinding CloseButtonStyle}" Height="17" Width="43" IsTabStop="False"> |
||||
|
<Path Height="10" HorizontalAlignment="Center" VerticalAlignment="Center" Width="12" Fill="#E4FFFFFF" Stretch="Fill" Stroke="#FF535666" |
||||
|
Data="M0.5,0.5 L4.5178828,0.5 L6.0620003,3.125 L7.4936447,0.5 L11.5,0.5 L11.5,1.5476431 L8.7425003,6.1201854 L11.5,10.359666 L11.5,11.5 L7.4941902,11.5 L6.0620003,8.8740005 L4.5172949,11.5 L0.5,11.5 L0.5,10.43379 L3.3059995,6.1201582 L0.5,1.4676378 L0.5,0.5 z"/> |
||||
|
</Button> |
||||
|
</Border> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,102 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class DecimalUpDown : NumericUpDown<decimal?> |
||||
|
{ |
||||
|
#region Constructors
|
||||
|
|
||||
|
static DecimalUpDown() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DecimalUpDown), new FrameworkPropertyMetadata(typeof(DecimalUpDown))); |
||||
|
DefaultValueProperty.OverrideMetadata(typeof(DecimalUpDown), new FrameworkPropertyMetadata(default(decimal))); |
||||
|
IncrementProperty.OverrideMetadata(typeof(DecimalUpDown), new FrameworkPropertyMetadata(1m)); |
||||
|
MaximumProperty.OverrideMetadata(typeof(DecimalUpDown), new FrameworkPropertyMetadata(decimal.MaxValue)); |
||||
|
MinimumProperty.OverrideMetadata(typeof(DecimalUpDown), new FrameworkPropertyMetadata(decimal.MinValue)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
protected override decimal? CoerceValue(decimal? value) |
||||
|
{ |
||||
|
if (value < Minimum) |
||||
|
return Minimum; |
||||
|
else if (value > Maximum) |
||||
|
return Maximum; |
||||
|
else |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
protected override void OnIncrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
Value += Increment; |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override void OnDecrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
Value -= Increment; |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override decimal? ConvertTextToValue(string text) |
||||
|
{ |
||||
|
decimal? result = null; |
||||
|
|
||||
|
if (String.IsNullOrEmpty(text)) |
||||
|
return result; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
result = FormatString.Contains("P") ? ParsePercent(text, CultureInfo) : ParseDecimal(text, CultureInfo); |
||||
|
result = CoerceValue(result); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
Text = ConvertValueToText(); |
||||
|
return Value; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
protected override string ConvertValueToText() |
||||
|
{ |
||||
|
if (Value == null) |
||||
|
return string.Empty; |
||||
|
|
||||
|
return Value.Value.ToString(FormatString, CultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected override void SetValidSpinDirection() |
||||
|
{ |
||||
|
ValidSpinDirections validDirections = ValidSpinDirections.None; |
||||
|
|
||||
|
if (Value < Maximum || !Value.HasValue) |
||||
|
validDirections = validDirections | ValidSpinDirections.Increase; |
||||
|
|
||||
|
if (Value > Minimum || !Value.HasValue) |
||||
|
validDirections = validDirections | ValidSpinDirections.Decrease; |
||||
|
|
||||
|
if (Spinner != null) |
||||
|
Spinner.ValidSpinDirection = validDirections; |
||||
|
} |
||||
|
|
||||
|
protected override void ValidateValue(decimal? value) |
||||
|
{ |
||||
|
if (value < Minimum) |
||||
|
Value = Minimum; |
||||
|
else if (value > Maximum) |
||||
|
Value = Maximum; |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,102 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class DoubleUpDown : NumericUpDown<double?> |
||||
|
{ |
||||
|
#region Constructors
|
||||
|
|
||||
|
static DoubleUpDown() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(DoubleUpDown), new FrameworkPropertyMetadata(typeof(DoubleUpDown))); |
||||
|
DefaultValueProperty.OverrideMetadata(typeof(DoubleUpDown), new FrameworkPropertyMetadata(default(double))); |
||||
|
IncrementProperty.OverrideMetadata(typeof(DoubleUpDown), new FrameworkPropertyMetadata(1d)); |
||||
|
MaximumProperty.OverrideMetadata(typeof(DoubleUpDown), new FrameworkPropertyMetadata(double.MaxValue)); |
||||
|
MinimumProperty.OverrideMetadata(typeof(DoubleUpDown), new FrameworkPropertyMetadata(double.MinValue)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
protected override double? CoerceValue(double? value) |
||||
|
{ |
||||
|
if (value < Minimum) |
||||
|
return Minimum; |
||||
|
else if (value > Maximum) |
||||
|
return Maximum; |
||||
|
else |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
protected override void OnIncrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
Value += Increment; |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override void OnDecrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
Value -= Increment; |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override double? ConvertTextToValue(string text) |
||||
|
{ |
||||
|
double? result = null; |
||||
|
|
||||
|
if (String.IsNullOrEmpty(text)) |
||||
|
return result; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
result = FormatString.Contains("P") ? Decimal.ToDouble(ParsePercent(text, CultureInfo)) : ParseDouble(text, CultureInfo); |
||||
|
result = CoerceValue(result); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
Text = ConvertValueToText(); |
||||
|
return Value; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
protected override string ConvertValueToText() |
||||
|
{ |
||||
|
if (Value == null) |
||||
|
return string.Empty; |
||||
|
|
||||
|
return Value.Value.ToString(FormatString, CultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected override void SetValidSpinDirection() |
||||
|
{ |
||||
|
ValidSpinDirections validDirections = ValidSpinDirections.None; |
||||
|
|
||||
|
if (Value < Maximum || !Value.HasValue) |
||||
|
validDirections = validDirections | ValidSpinDirections.Increase; |
||||
|
|
||||
|
if (Value > Minimum || !Value.HasValue) |
||||
|
validDirections = validDirections | ValidSpinDirections.Decrease; |
||||
|
|
||||
|
if (Spinner != null) |
||||
|
Spinner.ValidSpinDirection = validDirections; |
||||
|
} |
||||
|
|
||||
|
protected override void ValidateValue(double? value) |
||||
|
{ |
||||
|
if (value < Minimum) |
||||
|
Value = Minimum; |
||||
|
else if (value > Maximum) |
||||
|
Value = Maximum; |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,103 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class IntegerUpDown : NumericUpDown<int?> |
||||
|
{ |
||||
|
#region Constructors
|
||||
|
|
||||
|
static IntegerUpDown() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(typeof(IntegerUpDown))); |
||||
|
DefaultValueProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(0)); |
||||
|
IncrementProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(1)); |
||||
|
MaximumProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(int.MaxValue)); |
||||
|
MinimumProperty.OverrideMetadata(typeof(IntegerUpDown), new FrameworkPropertyMetadata(int.MinValue)); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Base Class Overrides
|
||||
|
|
||||
|
protected override int? CoerceValue(int? value) |
||||
|
{ |
||||
|
if (value < Minimum) |
||||
|
return Minimum; |
||||
|
else if (value > Maximum) |
||||
|
return Maximum; |
||||
|
else |
||||
|
return value; |
||||
|
} |
||||
|
|
||||
|
protected override void OnIncrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
Value += Increment; |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override void OnDecrement() |
||||
|
{ |
||||
|
if (Value.HasValue) |
||||
|
Value -= Increment; |
||||
|
else |
||||
|
Value = DefaultValue; |
||||
|
} |
||||
|
|
||||
|
protected override int? ConvertTextToValue(string text) |
||||
|
{ |
||||
|
int? result = null; |
||||
|
|
||||
|
if (String.IsNullOrEmpty(text)) |
||||
|
return result; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
//don't know why someone would format an integer as %, but just in case they do.
|
||||
|
result = FormatString.Contains("P") ? Decimal.ToInt32(ParsePercent(text, CultureInfo)) : ParseInt(text, CultureInfo); |
||||
|
result = CoerceValue(result); |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
Text = ConvertValueToText(); |
||||
|
return Value; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
protected override string ConvertValueToText() |
||||
|
{ |
||||
|
if (Value == null) |
||||
|
return string.Empty; |
||||
|
|
||||
|
return Value.Value.ToString(FormatString, CultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected override void SetValidSpinDirection() |
||||
|
{ |
||||
|
ValidSpinDirections validDirections = ValidSpinDirections.None; |
||||
|
|
||||
|
if (Value < Maximum || !Value.HasValue) |
||||
|
validDirections = validDirections | ValidSpinDirections.Increase; |
||||
|
|
||||
|
if (Value > Minimum || !Value.HasValue) |
||||
|
validDirections = validDirections | ValidSpinDirections.Decrease; |
||||
|
|
||||
|
if (Spinner != null) |
||||
|
Spinner.ValidSpinDirection = validDirections; |
||||
|
} |
||||
|
|
||||
|
protected override void ValidateValue(int? value) |
||||
|
{ |
||||
|
if (value < Minimum) |
||||
|
Value = Minimum; |
||||
|
else if (value > Maximum) |
||||
|
Value = Maximum; |
||||
|
} |
||||
|
|
||||
|
#endregion //Base Class Overrides
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,149 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Input; |
||||
|
using Microsoft.Windows.Controls.Primitives; |
||||
|
using System.Globalization; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public abstract class NumericUpDown<T> : UpDownBase<T> |
||||
|
{ |
||||
|
#region Properties
|
||||
|
|
||||
|
#region DefaultValue
|
||||
|
|
||||
|
public static readonly DependencyProperty DefaultValueProperty = DependencyProperty.Register("DefaultValue", typeof(T), typeof(NumericUpDown<T>), new UIPropertyMetadata(default(T))); |
||||
|
public T DefaultValue |
||||
|
{ |
||||
|
get { return (T)GetValue(DefaultValueProperty); } |
||||
|
set { SetValue(DefaultValueProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //DefaultValue
|
||||
|
|
||||
|
#region FormatString
|
||||
|
|
||||
|
public static readonly DependencyProperty FormatStringProperty = DependencyProperty.Register("FormatString", typeof(string), typeof(NumericUpDown<T>), new UIPropertyMetadata(String.Empty, OnFormatStringChanged)); |
||||
|
public string FormatString |
||||
|
{ |
||||
|
get { return (string)GetValue(FormatStringProperty); } |
||||
|
set { SetValue(FormatStringProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnFormatStringChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
NumericUpDown<T> numericUpDown = o as NumericUpDown<T>; |
||||
|
if (numericUpDown != null) |
||||
|
numericUpDown.OnFormatStringChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnFormatStringChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
if (IsInitialized) |
||||
|
Text = ConvertValueToText(); |
||||
|
} |
||||
|
|
||||
|
#endregion //FormatString
|
||||
|
|
||||
|
#region Increment
|
||||
|
|
||||
|
public static readonly DependencyProperty IncrementProperty = DependencyProperty.Register("Increment", typeof(T), typeof(NumericUpDown<T>), new PropertyMetadata(default(T))); |
||||
|
public T Increment |
||||
|
{ |
||||
|
get { return (T)GetValue(IncrementProperty); } |
||||
|
set { SetValue(IncrementProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region Maximum
|
||||
|
|
||||
|
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(T), typeof(NumericUpDown<T>), new UIPropertyMetadata(default(T), OnMaximumChanged)); |
||||
|
public T Maximum |
||||
|
{ |
||||
|
get { return (T)GetValue(MaximumProperty); } |
||||
|
set { SetValue(MaximumProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnMaximumChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
NumericUpDown<T> numericUpDown = o as NumericUpDown<T>; |
||||
|
if (numericUpDown != null) |
||||
|
numericUpDown.OnMaximumChanged((T)e.OldValue, (T)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnMaximumChanged(T oldValue, T newValue) |
||||
|
{ |
||||
|
SetValidSpinDirection(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Maximum
|
||||
|
|
||||
|
#region Minimum
|
||||
|
|
||||
|
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(T), typeof(NumericUpDown<T>), new UIPropertyMetadata(default(T), OnMinimumChanged)); |
||||
|
public T Minimum |
||||
|
{ |
||||
|
get { return (T)GetValue(MinimumProperty); } |
||||
|
set { SetValue(MinimumProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnMinimumChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
NumericUpDown<T> numericUpDown = o as NumericUpDown<T>; |
||||
|
if (numericUpDown != null) |
||||
|
numericUpDown.OnMinimumChanged((T)e.OldValue, (T)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnMinimumChanged(T oldValue, T newValue) |
||||
|
{ |
||||
|
SetValidSpinDirection(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Minimum
|
||||
|
|
||||
|
#region SelectAllOnGotFocus
|
||||
|
|
||||
|
public static readonly DependencyProperty SelectAllOnGotFocusProperty = DependencyProperty.Register("SelectAllOnGotFocus", typeof(bool), typeof(NumericUpDown<T>), new PropertyMetadata(false)); |
||||
|
public bool SelectAllOnGotFocus |
||||
|
{ |
||||
|
get { return (bool)GetValue(SelectAllOnGotFocusProperty); } |
||||
|
set { SetValue(SelectAllOnGotFocusProperty, value); } |
||||
|
} |
||||
|
|
||||
|
#endregion //SelectAllOnGotFocus
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
protected static decimal ParseDecimal(string text, IFormatProvider cultureInfo) |
||||
|
{ |
||||
|
return Decimal.Parse(text, NumberStyles.Any, cultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected static double ParseDouble(string text, IFormatProvider cultureInfo) |
||||
|
{ |
||||
|
return Double.Parse(text, NumberStyles.Any, cultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected static int ParseInt(string text, IFormatProvider cultureInfo) |
||||
|
{ |
||||
|
return Int32.Parse(text, NumberStyles.Any, cultureInfo); |
||||
|
} |
||||
|
|
||||
|
protected static decimal ParsePercent(string text, IFormatProvider cultureInfo) |
||||
|
{ |
||||
|
NumberFormatInfo info = NumberFormatInfo.GetInstance(cultureInfo); |
||||
|
|
||||
|
text = text.Replace(info.PercentSymbol, null); |
||||
|
|
||||
|
decimal result = Decimal.Parse(text, NumberStyles.Any, info); |
||||
|
result = result / 100; |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters" |
||||
|
xmlns:prims="clr-namespace:Microsoft.Windows.Controls.Primitives"> |
||||
|
|
||||
|
<coreConverters:InverseBoolConverter x:Key="InverseBoolConverter" /> |
||||
|
|
||||
|
<DataTemplate x:Key="DefaultWatermarkTemplate"> |
||||
|
<ContentControl Content="{Binding}" Foreground="Gray" Focusable="False" /> |
||||
|
</DataTemplate> |
||||
|
|
||||
|
<Style x:Key="NumericUpDown" TargetType="Control"> |
||||
|
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> |
||||
|
<Setter Property="BorderThickness" Value="1" /> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Right" /> |
||||
|
<Setter Property="VerticalContentAlignment" Value="Center" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="Control"> |
||||
|
<local:ButtonSpinner x:Name="Spinner" IsTabStop="False" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
AllowSpin="{Binding AllowSpin, RelativeSource={RelativeSource TemplatedParent}}" ShowButtonSpinner="{Binding ShowButtonSpinner, RelativeSource={RelativeSource TemplatedParent}}"> |
||||
|
<local:WatermarkTextBox x:Name="TextBox" BorderThickness="0" |
||||
|
Background="{TemplateBinding Background}" |
||||
|
FontFamily="{TemplateBinding FontFamily}" |
||||
|
FontSize="{TemplateBinding FontSize}" |
||||
|
FontStretch="{TemplateBinding FontStretch}" |
||||
|
FontStyle="{TemplateBinding FontStyle}" |
||||
|
FontWeight="{TemplateBinding FontWeight}" |
||||
|
Foreground="{TemplateBinding Foreground}" |
||||
|
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" |
||||
|
IsReadOnly="{Binding IsEditable, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" |
||||
|
MinWidth="20" AcceptsReturn="False" |
||||
|
SelectAllOnGotFocus="{Binding SelectAllOnGotFocus, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
TextAlignment="{Binding TextAlignment, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
TextWrapping="NoWrap" |
||||
|
TabIndex="{TemplateBinding TabIndex}" |
||||
|
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" |
||||
|
Watermark="{Binding Watermark, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
WatermarkTemplate="{Binding WatermarkTemplate, RelativeSource={RelativeSource TemplatedParent}}"/> |
||||
|
</local:ButtonSpinner> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- DecimalUpDown --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:DecimalUpDown}" BasedOn="{StaticResource NumericUpDown}"> |
||||
|
<Setter Property="TextAlignment" Value="Right" /> |
||||
|
<Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- DoubleUpDown --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:DoubleUpDown}" BasedOn="{StaticResource NumericUpDown}"> |
||||
|
<Setter Property="TextAlignment" Value="Right" /> |
||||
|
<Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
</Style> |
||||
|
|
||||
|
<!-- =============================================================================== --> |
||||
|
<!-- IntegerUpDown --> |
||||
|
<!-- =============================================================================== --> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:IntegerUpDown}" BasedOn="{StaticResource NumericUpDown}"> |
||||
|
<Setter Property="TextAlignment" Value="Right" /> |
||||
|
<Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}" /> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
@ -0,0 +1,68 @@ |
|||||
|
using System; |
||||
|
using System.Reflection; |
||||
|
using System.Resources; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Markup; |
||||
|
using System.Security; |
||||
|
|
||||
|
// General Information about an assembly is controlled through the following
|
||||
|
// set of attributes. Change these attribute values to modify the information
|
||||
|
// associated with an assembly.
|
||||
|
[assembly: AssemblyTitle("Extended WPF Toolkit")] |
||||
|
[assembly: AssemblyDescription("")] |
||||
|
[assembly: AssemblyConfiguration("")] |
||||
|
[assembly: AssemblyCompany("")] |
||||
|
[assembly: AssemblyProduct("Extended WPF Toolkit")] |
||||
|
[assembly: AssemblyCopyright("Copyright © 2010")] |
||||
|
[assembly: AssemblyTrademark("")] |
||||
|
[assembly: AssemblyCulture("")] |
||||
|
|
||||
|
// Needed to enable xbap scenarios
|
||||
|
[assembly: AllowPartiallyTrustedCallers] |
||||
|
|
||||
|
|
||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
|
// to COM components. If you need to access a type in this assembly from
|
||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||
|
[assembly: ComVisible(false)] |
||||
|
|
||||
|
[assembly: CLSCompliant(true)] |
||||
|
|
||||
|
//In order to begin building localizable applications, set
|
||||
|
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
|
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
|
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
|
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
|
//the line below to match the UICulture setting in the project file.
|
||||
|
|
||||
|
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
|
||||
|
|
||||
|
[assembly: ThemeInfo( |
||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// or application resource dictionaries)
|
||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
|
//(used if a resource is not found in the page,
|
||||
|
// app, or any theme specific resource dictionaries)
|
||||
|
)] |
||||
|
|
||||
|
|
||||
|
// Version information for an assembly consists of the following four values:
|
||||
|
//
|
||||
|
// Major Version
|
||||
|
// Minor Version
|
||||
|
// Build Number
|
||||
|
// Revision
|
||||
|
//
|
||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
|
// by using the '*' as shown below:
|
||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
[assembly: AssemblyVersion("1.4.0.3")] |
||||
|
[assembly: AssemblyFileVersion("1.4.0.3")] |
||||
|
|
||||
|
[assembly: XmlnsPrefix("http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended", "extToolkit")] |
||||
|
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended", "Microsoft.Windows.Controls")] |
||||
|
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended", "Microsoft.Windows.Controls.PropertyGrid")] |
||||
@ -0,0 +1,63 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.1
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Properties { |
||||
|
using System; |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources { |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() { |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager { |
||||
|
get { |
||||
|
if (object.ReferenceEquals(resourceMan, null)) { |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Windows.Controls.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture { |
||||
|
get { |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set { |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,117 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
</root> |
||||
@ -0,0 +1,26 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.1
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Microsoft.Windows.Controls.Properties { |
||||
|
|
||||
|
|
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] |
||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { |
||||
|
|
||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); |
||||
|
|
||||
|
public static Settings Default { |
||||
|
get { |
||||
|
return defaultInstance; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
<?xml version='1.0' encoding='utf-8'?> |
||||
|
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> |
||||
|
<Profiles> |
||||
|
<Profile Name="(Default)" /> |
||||
|
</Profiles> |
||||
|
<Settings /> |
||||
|
</SettingsFile> |
||||
|
After Width: | Height: | Size: 156 B |
|
After Width: | Height: | Size: 333 B |
|
After Width: | Height: | Size: 201 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 142 B |