Windows Presentation Foundation Agenda • • • • • • • • • Introduction Developing Applications WPF and WF interoperability Custom Controls Styles and Templates Data Binding Graphics Not covered sections Resume Introduction Progress • • • • WinAPI MFC Windows Forms WPF WPF Components Main features • • • • • • • • • • • New GUI core Declarative programming using XAML Layout system Styles Control Templates Data Templates Flexible Data Binding Graphics and Multimedia support Improved security model Unified document format (XML Paper Specification) Compatibility with Windows Forms Developing Applications Developer Environment • • • • Visual Studio 2005 .NET 3.0 Visual Studio Extensions Windows SDK Application types • XAML browser applications • Stand-alone applications – Windows Applications – Hosted in WPF Navigation Window XAML browser application • • • • WPF Everywhere for XAML + browser plug-in Installed using ClickOnce Run in browser Internet Zone security Stand-alone application • • User permissions Like a standard Windows Application Creating stand-alone application • Create WPF project – Windows Application (WPF) – Custom Control Library (WPF) • Create class – User Control (WPF) – Custom Control (WPF) – Window (WPF) • Create styles and templates – Resource dictionary – Local resource Kinds of WPF Project objects • User control – CS code-behind file – XAML declaration • Custom control – CS implementation – Style in XAML resource dictionary • XAML Resource – Style or Data Template or Control Template in XAML resource dictionary WPF Application Project structure • Application class (User control) – Based on System.Windows.Application – Build action – ApplicationDefinition – StartupUri property in XAML – Window class • Window class (User control) – Based on System.Windows.Window • User Control class (User control) – Based on System.Windows.Controls.UserControl • Custom Control class (Custom control) – Based on System.Windows.Controls.Control – Overrides metadata in static constructor • Resource Dictionary (XAML Resource) – Top file tag ResourceDictionary – Main file “themes\generic.xaml” WPF Application Project screen shot WPF and WF interoperability WPF and WF interoperability Agenda • Hosting a Windows Form Control in WPF • Hosting a WPF Control in Windows Forms • Troubleshooting Hybrid Applications Hosting a WF Control in WPF 1. Create Windows Application (WPF) project 2. Add reference to the WindowsFormsIntegration assembly 3. Add reference to the System.Windows.Forms assembly 4. Create System.Windows.Forms.Integration. WindowsFormsHost host object 5. Set WF control to Child property of host object 6. Add host object onto WPF panel (for example, Window) Hosting a WF Control in WPF - sample // Creating Windows Form control MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000"); // Creating Integration host WindowsFormsHost host = new WindowsFormsHost(); host.Child = mtbDate; // Appending host to Window this.AddChild(host); Hosting a WPF Control in WF 1. Create Windows Application (WinForms) project 2. Add references to WindowsFormsIntegration, PresentationCore, PresentationFramework and WindowsBase assemblies 3. Add into project file the following line : <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" /> Just after <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 5. Create System.Windows.Forms.Integration.ElementHost host object 6. Add WPF control to host object 7. Add host object on WF Form Hosting a WPF Control in WF // Create WPF Control TextBlock textBlock = new TextBlock(); textBlock.Text = "WPF TextBlock control"; // Create host ElementHost host = new ElementHost(); host.Child = textBlock; host.Dock = DockStyle.Fill; // Add host to Form this.Controls.Add(host); Troubleshooting Hybrid Applications • • • • • • Overlapping Controls Child Property Scaling Adapter Nesting Focus • • • • • • • Property Mapping Layout-related Properties on Hosted Content Navigation Applications Opacity and Layering Dispose Enabling Visual Styles Licensed Controls Custom Controls Models for Control Authoring • • • • Restyle existed controls Derive from UserControl Derive from Control Derive from FrameworkElement Restyle existed controls • Simplest way • No additional properties • Custom control logic only in XAML Restyle existed controls – example <Window x:Class="RestyleControls.Window"> <Window.Resources> <Style TargetType="{x:Type TextBox}"> <Setter Property="Background" Value="Red"/> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="FontStyle" Value="Italic" /> <Setter Property="Foreground" Value="Blue" /> </Style> </Window.Resources> <StackPanel> <TextBox Text="Restyled TextBox"/> </StackPanel> </Window> Restyle existed controls – screen shot Derive from UserControl • Built like Application • Composite of existed controls • No complex customization Deriving from UserControl - example <UserControl x:Name="parent“ x:Class="UserControls.UserControl"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding ElementName=parent,Path=LabelText}" Margin="5"/> <TextBox Text="{Binding ElementName=parent,Path=ValueText}" Margin="5"/> </StackPanel> </UserControl> Deriving from UserControl – example <Window x:Class="UserControls.Window" xmlns:l="clr-namespace:UserControls"> <StackPanel> <l:UserControl LabelText="Label Text“ ValueText="Value Text"/> </StackPanel> </Window> Deriving from UserControl – screen shot Deriving from Control • • • • Flexible way Like most WPF controls Support Control Templates Support Themes Deriving from Control - example <Style TargetType="{x:Type local:EditControl}" > <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:EditControl}"> <Grid Name="TextBoxGrid"> <Border Name="Border" Padding="2" BorderThickness="0" > <TextBox Name="ContentTextBox" Text="Text!" OverridesDefaultStyle="True"> <TextBox.Template> <ControlTemplate TargetType="{x:Type TextBox}"> <ScrollViewer Margin="6,0,6,0" x:Name="PART_ContentHost" VerticalAlignment="Center" /> </ControlTemplate> </TextBox.Template> </TextBox> </Border> <TextBlock Name="MandText" Margin="0,0,6,0" HorizontalAlignment="Right" VerticalAlignment="Center" Visibility="Hidden" Text="*"/> <Ellipse Stroke="Blue"/> <Grid Name="FocusBrackets" Visibility="Hidden" > <Line StrokeThickness="1" Stroke="Red" X1="1" Y1="1" X2="1" Y2=“…"/> <Line StrokeThickness="1" Stroke="Red" X1="1" Y1="1" X2="10" Y2="1"/> </Grid> </Grid> <ControlTemplate.Triggers> <Trigger Property="Mandatory" Value="True"> <Setter TargetName="MandText" Property="Visibility" Value="Visible"/> </Trigger> <Trigger SourceName="ContentTextBox" Property="IsFocused" Value="True"> <Setter TargetName="FocusBrackets" Property="Visibility" Value="Visible"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> Deriving from FrameworkElement • Own Render way • Appearance is defined by own render logic Styles and Templates Styling and Templating • • • • • Resources Style structure Data Templates Control Templates Triggers Styling and Templating - Resources • Store local Styles, Data Templates and Control Templates • Apply to FrameworkElement and FrameworkContentElement • Share resources via Resource Dictionaries • Static and Dynamic resources Resources example <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:ControlLibrary"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Shared.xaml"/> </ResourceDictionary.MergedDictionaries> <Style TargetType="{x:Type local:EditControl}" > <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:EditControl}"> <Grid Name="TextBoxGrid"> <TextBox Name="ContentTextBox" Text="Text!" OverridesDefaultStyle="True“/> </Grid> <ControlTemplate.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition SourceName="ContentTextBox" Property="Text" Value=""/> <Condition Property="Mandatory" Value="True"/> </MultiTrigger.Conditions> <Setter TargetName="MandText" Property="Visibility" Value="Visible"/> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> Styling and Templating – Style structure • • • • • • Naming and Referencing Deriving Styles Setters Data Template Control Template Triggers Styling and Templating – Data Templates • • • • Name and Data Type Visual data content Content Control and Content Presenter Triggers Styling and Templating – Control Templates • • • • Name and Target Type Visual data content Template Attributes Triggers Styling and Templating – Triggers • Trigger and Multi Trigger <Trigger Property="IsMouseOver" Value="true"> <Setter Property = "Background" Value="Red"/> </Trigger> • Data Trigger and Multi Data Trigger <DataTrigger Binding="{Binding Path=State}" Value="WA"> <Setter Property="Foreground" Value="Red" /> </DataTrigger> • Event Trigger and Multi Event Trigger <EventTrigger RoutedEvent="MouseLeave"> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:1.5" AccelerationRatio="0.10“ DecelerationRatio="0.25" Storyboard.TargetProperty="(Canvas.Width)" /> </Storyboard> </BeginStoryboard> </EventTrigger> Data Binding Binding a dependency property to a CLR property <TextBox ...> <TextBox.Text> <Binding Path="Age" /> </TextBox.Text> </TextBox> <TextBox TextContent="{Binding Path=Age}" /> <TextBox TextContent="{Binding Age}" /> • Path == DaraSource • Binding only to dependency properties Data Context 1. The binding looks for a non-null DataContext on the TextBox itself 2. The binding looks for a non-null DataContext on the Grid 3. The binding looks for a non-null DataContext on the Window Master-Detail Binding public class Families : ObservableCollection<Family> { } public class Family { string familyName; public string FamilyName { get { return familyName; } set { familyName = value; } } People members; public People Members { get { return members; } set { members = value; } } public class People : ObservableCollection<Person> { } public class Person { string name; public string Name { get { return name; } set { name = value; } } int age; public int Age { get { return age; } set { age = value; } } } } Master-Detail Binding <!-- Window1.xaml --> <?Mapping XmlNamespace="local" ClrNamespace="MasterDetailBinding" ?> <Window ... xmlns:local="local"> <Window.Resources> <local:Families x:Key="Families"> <local:Family FamilyName="Stooge"> <local:Family.Members> <local:People> <local:Person Name="Larry" Age="21" /> <local:Person Name="Moe" Age="22" /> <local:Person Name="Curly" Age="23" /> </local:People> </local:Family.Members> </local:Family> <local:Family FamilyName="Addams"> <local:Family.Members> <local:People> <local:Person Name="Gomez" Age="135" /> <local:Person Name="Morticia" Age="121" /> <local:Person Name="Fester" Age="137" /> </local:People> </local:Family.Members> </local:Family> </local:Families> </Window.Resources> ... </Window> Master-Detail Binding <!-- Window1.xaml --> <?Mapping ... ?> <Window ...> <Window.Resources> <local:Families x:Key="Families">...</local:Families> </Window.Resources> <Grid DataContext="{StaticResource Families}"> ... <!-- Families Column --> <TextBlock Grid.Row="0" Grid.Column="0">Families:</TextBlock> <ListBox Grid.Row="1" Grid.Column="0" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock TextContent="{Binding Path=FamilyName}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window> Graphics Not covered sections Sections • • • • Security model Web Browser Applications Using multimedia and graphics Easy to restyle application Resume Advantages • • • • WPF has very flexible model XAML is a great advance in declarative programming Easy to use multimedia and graphics Easy to restyle application Disadvantages • • • • WPF functionality is not so high as WF one WPF and WF interoperability is buggy VS support of XAML is buggy and not full Most available WPF documentation is out of date