290 likes | 465 Views
WPF Control Customization. Atlanta .NET Users Group March 2007. Who Am I?. Shawn Wildermuth swildermuth@adoguy.com Wildermuth Consulting Services http://wildermuthconsulting.com C# MVP, MCSD, MCT, INETA Speaker Book Author Pragmatic ADO.NET MCTS Training Kit (Exam 536)
E N D
WPF Control Customization Atlanta .NET Users Group March 2007
Who Am I? • Shawn Wildermuth • swildermuth@adoguy.com • Wildermuth Consulting Services • http://wildermuthconsulting.com • C# MVP, MCSD, MCT, INETA Speaker • Book Author • Pragmatic ADO.NET • MCTS Training Kit (Exam 536) • MCPD Training Kits (Exams 547, 548 & 549) • Programming WPF (Authored “WPF/E” Appendix only) • Prescriptive Data Architectures – Upcoming
Agenda • Introduction • Composition • Styles • Templates • User Controls • Custom Controls
What You Will Learn • If you’re already doing WPF… • When and how to customize your controls • How Styling, Templates and Controls work • If you have not yet started doing WPF… • Why WPF’s Control model is dramatically superior • Why you will love to abandon OwnerDraw
Improved Control Customization • GDI Challenges • Controls are not flexible • Properties are the path to customization • Owner-drawing controls are expensive • Advanced customization requires significantly more work.
Better Customization Composition does not require customization Controls have flexible styling model Control Templates for advance look/feel changes User and Custom Controls for edge cases Improved Control Customization (2)
“Do I really need a custom control?” • “I want to create a composite control” • Use Composition • “I want to have a consistent look/feel to my control” • Use Styling • “I want to change the look of an existing control” • Use Templates • “I want new behavior” • Create a user or custom control
Composition • Some controls can contain other controls • ContentControl base class defines Content property • Can contain other objects <StackPanelxmlns="..." xmlns:x="..."> <Button Width="50" Height="50" Content="Play" /> <Polygon HorizontalAlignment="Center" Points="0,0 0,26 17,13" Fill="Black" /> </StackPanel> <StackPanelxmlns="..." xmlns:x="..."> <Button Height="50" Width="50"> <StackPanel> <TextBlock>Play</TextBlock> <Polygon Points="0,0 0,26 17,13" Fill="Black" /> </StackPanel> </Button> </StackPanel>
WPF Styling • WPF Supports “CSS Style” Styling of controls • Both Named Items and Item Classes supported • Allows shared changes to Properties only • Can ‘style’ a control but not change it significantly <StackPanelxmlns="..." xmlns:x="..."> <Button Width="100" Content="First" /> <Button Width="100" Content="Second" /> </StackPanel> <StackPanelxmlns="..." xmlns:x="..."> <StackPanel.Resources> <Style TargetType="Button" x:Key="RedButton"> <Setter Property="BorderBrush" Value="Red" /> </Style> </StackPanel.Resources> <Button Width="100" Content="First" /> <Button Width="100" Content="Second" Style="{StaticResourceRedButton}" /> </StackPanel> <StackPanelxmlns="..." xmlns:x="..."> <StackPanel.Resources> <Style TargetType="Button"> <Setter Property="BorderBrush" Value="Red" /> </Style> </StackPanel.Resources> <Button Width="100" Content="First" /> <Button Width="100" Content="Second" /> </StackPanel>
WPF Templates • Allows re-definition of build-in controls • Can redefine the XAML that is used to build control • Look can be changed dramatically by changing XAML • Feel can be changed with Triggers and Animations • Cannot add non-trigger behavior • E.g. no new methods, properties or events
Writing Your Own Controls • Two ways • User Controls • Simple development model (similar to application dev) • Need to compose control of only existing components • Do not need customization (e.g. templates and styles) • Custom Controls • Want full control over the look and feel of new control • Need special rendering support • Want to support being a container for other controls
User Control Development • Typical WPF-like Development Experience • Write XAML that defines the control • Similar to WinForms and ASP.NET User Controls • XAML + CodeBehind <UserControl x:Class="CustomWPF.MyUserControl" xmlns="..." xmlns:x="..."> <Grid> <Ellipse Width="50" Height="50" Name="ButtonBack" /> <Path Name="PlayIcon" Fill="Black" Data="M18,12 18,38 35,25"/> </Grid> </UserControl> public partial class MyUserControl : UserControl { public MyUserControl (){ PlayIcon.Opacity = .5; } }
User Control Development (2) • Use Controls by importing the CLR Namespace • You import the entire namespace, not individual classes • Can use new control in XAML • Specify the xml namespace and the type name • If control is in another assembly, you specify the name <Window x:Class="Tester.MainWindow" xmlns="..." xmlns:x="..." xmlns:cust="clr-namespace:CustomWPF"> <cust:MyUserControl /> </Window> <Window x:Class="Tester.MainWindow" xmlns="..." xmlns:x="..." xmlns:cust="clr-namespace:CustomWPF, MyAssembly"> <cust:MyUserControl /> </Window>
Properties • Adding Properties is simple • CLR Properties work in XAML public partial class MyUserControl : UserControl { // ... Brush _iconColor = Brushes.Black; public Brush IconColor { get { return _iconColor; } set { _iconColor = value; PlayIcon.Fill = value; PauseIcon.Fill = value; } } }
Properties (2) • CLR Properties limited in functionality • Simple assignment work • Only works with simple code or XAML assignment <StackPanel> <Rectangle Name="aRect" Fill="Red" /> <TextBlock>User Control:</TextBlock> <!-- Simple Assignment Works --> <cust:MyUserControlIconColor="Blue" /> <!-- Data Binding Does Not --> <cust:MyUserControlIconColor="{Binding ElementName=aRect, Path=Fill}" /> </StackPanel>
Properties (3) • DependencyProperties • Allows values to be set without using Reflection • Objects register their properties • Support rich use of all WPF’s functionality • Data binding • Animation • Triggers
Properties (4) • DependencyProperties • Registration creates the runtime metadata • Optionally define change notification and default value public static readonlyDependencyPropertyIconColorProperty = DependencyProperty.Register("IconColor", // Property Name typeof(Brush), // Type of the Property typeof(PlayButton)); // Type of the Owner // of the Property
Properties (5) • DependencyProperties • Storage handled in WPF stack, not in your class public Brush IconColor { get { return (Brush)GetValue(IconColorProperty); } set { SetValue(IconColorProperty, value); } }
Custom Controls • Unlike User Controls • No base class requirements • Pay for Play choices of features • You decide how much or little you want • Pay == Labor involved in development, not runtime • Support for • Styling • Templates • Theming
Custom Controls (2) • In Visual Studio creating a new Custom Control • Creates a class that derives from Control • Builds a default theme template
Custom Controls (3) • New control can derive from any of the classes public class MyNewControl : Control { // ... } public class MyNewControl : FrameworkElement { // ... } public class MyNewControl : Button { // ... }
Custom Controls (4) • Which class is right? • Higher • Less Built-in Functionality • More Control • Lower • More Built-in Functionality • Less Control
Custom Controls (3) • Also creates (or adds to generic.xaml) <!-- Generic.xaml --> <ResourceDictionaryxmlns="..." xmlns:x="..." xmlns:local="clr-namespace:CustomWPF"> <Style TargetType="{x:Type local:MyNewControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplateTargetType="{x:Type local:MyNewControl}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBindingBorderBrush}" BorderThickness="{TemplateBindingBorderThickness}"> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> This is just a Template
Custom Controls (4) • Themes allow you to create designs that fit the OS • Theme files are resource dictionaries • Each is for different OS theme • Generic.xaml: The fallback theme file. • Luna.normalcolor.xaml: Windows XP Blue Theme • Luna.homestead.xaml: Windows XP Olive Theme • Luna.metalic.xaml: Windows XP Silver Theme • Aero.normalcolor.xaml: Windows Vista Theme • Classic.xaml: Windows Classic Theme
Custom Controls (5) • Custom Control Development is different • In WPF Development: • You are working with a XAML file that describes the UI • You can access the hierarchy as properties • In Custom Control Development: • The template should do as much of the behavior as possible • Events should do the rest • The more functionality you put in the code • The Less users can override that behavior
Questions? WPF Control Customization Links: My Website (www.wildermuthconsulting.com) My Blog (www.adoguy.com) Presentation and code available there My E-mail (swildermuth@adoguy.com) MSDN Magazine Article May Issue will contain my article on this (no link yet)