Skip to content

Instantly share code, notes, and snippets.

@TheVice
Last active November 12, 2018 21:43
Show Gist options
  • Save TheVice/e1da2ec1d4999c247a081392c05c68c3 to your computer and use it in GitHub Desktop.
Save TheVice/e1da2ec1d4999c247a081392c05c68c3 to your computer and use it in GitHub Desktop.
Starting from Windows 8 theme of WPF button by default flat. If require Vista theme, a.k.a. Chrome decorator, at Windows 8 and up theme can be apply by next approach.
/*
*
* The MIT License (MIT)
*
* Copyright (c) 2018 https://github.com/TheVice/
*
* As reference used program samples
* BuildButtonFactory from chapter 11 - "Single-Child Elements" of "Applications = Code + Markup" by Charles Petzold (2006) (ISBN 978-0-7356-1957-9)
* and
* ControlTemplateBrowser from chapter 15 - "Control Templates" at "Dissecting Controls" section of
* "Pro WPF in C# 2008 Windows Presentation Foundation with .NET 3.5" Second Edition by Matthew MacDonald (2008) (ISBN 978-1-4302-0576-0)
*
*/
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Markup;
using System.Windows.Controls;
using System.Windows.Documents;
using Microsoft.Windows.Themes;
using System.Windows.Controls.Primitives;
/*
* Microsoft.Windows.Themes can be found in references at next locations - depend on Theme name and version of .NET Framework.
*
* "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.Aero.dll"
* "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.Luna.dll"
* "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\PresentationFramework.Royale.dll"
*
* "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.Aero.dll"
* "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.Luna.dll"
* "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.Royale.dll"
*
*/
namespace WpfApplication
{
class BuildVistaButtonFactory : Window
{
ControlTemplate GetControlTemplateFromXmlFile(string path)
{
using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
using (XmlReader xmlReader = XmlReader.Create(fileStream))
{
try
{
return (ControlTemplate)XamlReader.Load(xmlReader);
}
catch (XamlParseException)
{
string content = File.ReadAllText(path);
using (StringReader stringReader = new StringReader(content))
{
using (XmlReader xmlReader_ = XmlReader.Create(stringReader))
{
return (ControlTemplate)XamlReader.Load(xmlReader_);
}
}
}
}
}
}
string GetXamlFromControlTemplate(ControlTemplate template)
{
StringBuilder stringBuilder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(stringBuilder, settings))
{
XamlWriter.Save(template, writer);
}
return stringBuilder.ToString();
}
void ButtonOnClick(object sender, RoutedEventArgs args)
{
MessageBox.Show("You clicked the button!", Title);
}
public BuildVistaButtonFactory()
{
ControlTemplate template = new ControlTemplate(typeof(ButtonBase));
FrameworkElementFactory factoryDecorator =
new FrameworkElementFactory(typeof(ButtonChrome));
factoryDecorator.Name = "Chrome";
factoryDecorator.SetValue(Control.BackgroundProperty, new TemplateBindingExtension(Panel.BackgroundProperty));
factoryDecorator.SetValue(Control.BorderBrushProperty, new TemplateBindingExtension(Border.BorderBrushProperty));
factoryDecorator.SetValue(ButtonChrome.RenderDefaultedProperty, new TemplateBindingExtension(Button.IsDefaultedProperty));
factoryDecorator.SetValue(ButtonChrome.RenderMouseOverProperty, new TemplateBindingExtension(UIElement.IsMouseOverProperty));
factoryDecorator.SetValue(ButtonChrome.RenderPressedProperty, new TemplateBindingExtension(ButtonBase.IsPressedProperty));
factoryDecorator.SetValue(FrameworkElement.NameProperty, "Chrome");
factoryDecorator.SetValue(UIElement.SnapsToDevicePixelsProperty, true);
FrameworkElementFactory factoryContent = new FrameworkElementFactory(typeof(ContentPresenter));
factoryContent.SetValue(ContentPresenter.RecognizesAccessKeyProperty, true);
factoryContent.SetValue(ContentControl.ContentProperty, new TemplateBindingExtension(ContentControl.ContentProperty));
factoryContent.SetValue(ContentControl.ContentTemplateProperty, new TemplateBindingExtension(ContentControl.ContentTemplateProperty));
factoryContent.SetValue(ContentPresenter.ContentStringFormatProperty, new TemplateBindingExtension(ContentControl.ContentStringFormatProperty));
factoryContent.SetValue(FrameworkElement.MarginProperty, new TemplateBindingExtension(Control.PaddingProperty));
factoryContent.SetValue(Control.HorizontalAlignmentProperty, new TemplateBindingExtension(Control.HorizontalAlignmentProperty));
factoryContent.SetValue(Control.VerticalAlignmentProperty, new TemplateBindingExtension(Control.VerticalAlignmentProperty));
factoryContent.SetValue(UIElement.SnapsToDevicePixelsProperty, new TemplateBindingExtension(UIElement.SnapsToDevicePixelsProperty));
factoryDecorator.AppendChild(factoryContent);
template.VisualTree = factoryDecorator;
Trigger trig = new Trigger();
trig.Property = UIElement.IsKeyboardFocusedProperty;
trig.Value = true;
Setter set = new Setter();
set.Property = ButtonChrome.RenderDefaultedProperty;
set.Value = true;
set.TargetName = "Chrome";
trig.Setters.Add(set);
template.Triggers.Add(trig);
trig = new Trigger();
trig.Property = ToggleButton.IsCheckedProperty;
trig.Value = true;
set = new Setter();
set.Property = ButtonChrome.RenderPressedProperty;
set.Value = true;
set.TargetName = "Chrome";
trig.Setters.Add(set);
template.Triggers.Add(trig);
trig = new Trigger();
trig.Property = UIElement.IsEnabledProperty;
trig.Value = false;
set = new Setter();
set.Property = TextElement.ForegroundProperty;
set.Value = new SolidColorBrush(Color.FromArgb(255, 173, 173, 173));
trig.Setters.Add(set);
template.Triggers.Add(trig);
//string code = GetXamlFromControlTemplate(template);
Button btn = new Button();
btn.Template = template;
btn.Content = "Button with Custom Template";
btn.Padding = new Thickness(20);
btn.FontSize = 24;
btn.HorizontalAlignment = HorizontalAlignment.Center;
btn.VerticalAlignment = VerticalAlignment.Center;
btn.Click += ButtonOnClick;
Content = btn;
}
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new BuildVistaButtonFactory());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment