WPF 体系结构

  • System.Object: 在 .NET 中所有类型的根类型
  • System.Windows.Threading.DispatcherObject: WPF 中的大多数对象都是从 DispatcherObject 派生的,这提供了用于处理并发和线程的基本构造。WPF 基于调度程序实现的消息系统。
  • System.Windows.DependencyObject: 表示一个参与依赖项属性系统的对象。
  • System.Windows.Media.Visual: 为 WPF 中的呈现提供支持,其中包括命中测试、坐标转换和边界框计算。
  • System.Windows.UIElement: UIElement 是 WPF 核心级实现的积累,该类建立在 WPF 元素和基本表示特征基础上。
  • System.Windows.FrameworkElement:
    • System.Windows.Controls.Control: 表示用户界面 UI 元素的基类,这些元素使用 ControlTemplate 来定义其外观。
      • System.Windows.Controls.ContentControl: 表示包含单项内容的控件。
      • System.Windows.Controls.ItemsControl: 表示一个可用于呈现项的集合的控件。
    • System.Windows.Controls.Decorator: 提供在单个子元素(如 Border 或 Viewbox)上或周围应用效果的元素的基类。
    • System.Windows.Controls.Image: 表示显示图像的控件。
    • System.Windows.Controls.MediaElement: 表示包含音频或视频的控件。
    • System.Windows.Controls.Panel: 为所有 Panel 元素提供基类。使用 Panel 元素在 WPF 应用程序中放置和排列子对象。
    • System.Windows.Sharps.Sharp: 为 Ellipse、Polygon 和 Rectangle 之类的形状元素提供基类。

WPF应用程序管理

创建WPF应用程序有两种方式

  1. Visual Studio和Expression Blend默认的方式,使用App.xaml文件定义启动应用程序

    <Application x:Class="WpfApplicationLifeCycle.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml">
        <Application.Resources>
        </Application.Resources>
    </Application>
    
  2. 可以自已定义类,定义Main方法实现对WPF应用程序的启动

    using System;
    using System.Windows;
    
    namespace WpfApplicationLifeCycle
    {
        public class MainClass
        {
            [STAThread]
            static void Main()
           {
               // 定义Application对象
               Application app = new Application();
    
               // 方法一:调用Run方法,参数为启动的窗体对象
               Window2 win = new Window2();
               app.Run(win);
    
               // 方法二:指定Application对象的MainWindow属性为启动窗体,调用无参数的Run方法
               //Window2 win = new Window2();
               //app.MainWindow = win;
               //win.Show();           // 此处必须有win.Show(),否则不能显示窗体
               //app.Run();
    
               // 方法三:
               //app.StartupUri = new Uri("Window2.xaml", UriKind.Relative);
               //app.Run();
           }
       }
    }
    

应用程序关闭

应用程序关闭时的策略由ShutdownMode属性指定,其类型为System.Windows.ShutdownMode枚举类型,其枚举成员有:

  • OnLastWindowClose(默认值):当应用程序中的最后一个窗体关闭时或调用Application对象的Shutdown()方法时,应用程序关闭。
  • OnMainWindowClose:当主窗体(即启动窗体)关闭时或调用Application对象的Shutdown()方法时,应用程序关闭。(类似于C#的Windows应用程序的关闭模式)
  • OnExplicitShutdown:只有在调用Application对象的Shutdown()方法时,应用程序才会关闭。

更改的时候,可以直接在App.xaml中更改:

<Application x:Class="WpfApplicationLifeCycle.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="Window1.xaml"
    ShutdownMode="OnExplicitShutdown">
    <Application.Resources>
    </Application.Resources>
</Application>

也可以在代码文件(App.xaml.cs)中更改

Application app = new Application();
Window2 win = new Window2();

// 更改关闭模式必须要在调用app.Run()方法之前
app.ShutdownMode = ShutdownMode.OnExplicitShutdown;
app.Run(win);

Application 对象的事件

  • Actived: 当应用程序成为前台应用程序时发生。
  • Deactived: 当应用程序停止作为前台应用程序时发生。
  • DispatcherUnhandledException: 在异常由应用程序引发但未进行处理时发生。
  • Exit: 恰好在应用程序关闭之前发生,且无法取消。
  • FragmengNavigation: 当应用程序中的导航器开始导航至某个内容片段时发送,如果所需片段位于当前内容在,则导航会立即发生,火灾,如果所需片段位于不同容器中,则导航会在加载了源 XAML 内容之后发生。
  • LoadCompleted: 在已经加载、分析并开始呈现应用程序中的导航器导航到的内容时发生。
  • Navigated: 在已经找到应用程序中的导航器要导航到的内容时发生,尽管此刻该内容可能尚未完成加载。
  • Navigating: 在应用程序中的导航器请求新的导航时发生。
  • NavigationFailed: 在应用程序中的导航器在导航到锁清秋内容时出现错误的情况下发生。
  • NavigationProgress: 在由应用程序中的导航器管理的下载过程中定期发送,以提高导航进度信息。
  • NavigationStopped: 在调用应用程序中的导航器的 StopLoading 方法时发生,或者当导航器在当前导航正在进行期间请求了一个新的导航时发生。
  • SessionEnding: 在用户通过注销或关闭操作系统而结束 Windows 会话时发生。
  • Startup: 在调用 Application 对象的 Run 方法时发生。

应用程序的事件处理

  1. 在App.xaml中做事件的绑定,在App.xaml.cs文件中添加事件的处理方法

    在App.xaml文件中:

    <Application x:Class="WpfApplicationLifeCycle.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="Window1.xaml"
        Startup="Application_Startup">
        <Application.Resources>
        </Application.Resources>
    </Application>
    

    在App.xaml.cs文件中:

    using System.Windows;
    
    namespace WpfApplicationLifeCycle
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
           private void Application_Startup(object sender, StartupEventArgs e)
           {
               // 定义应用程序启动时要处理的内容
           }
       }
    }
    
  2. 在自定义的类中可以做正常的C#的事件绑定:

    [STAThread]
    static void Main()
    {
        // 定义Application对象
        Application app = new Application();
        Window2 win = new Window2();
    
        // 添加事件的绑定
        app.Startup += new StartupEventHandler(app_Startup);
    
       app.Run(win);
    }
    
    static void app_Startup(object sender, StartupEventArgs e)
    {
       // 定义应用程序启动时要处理的内容
    }
    

WPF窗体

定义异形窗体

使用异形窗体,可以将窗体的背景设置为透明,边框设置为空,然后利用控件做出异形的窗体,例如:

XAML:

<Window x:Class="WpfWindow.CustomerWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="NonRectangularWindowSample" SizeToContent="WidthAndHeight" 
    MouseLeftButtonDown="NonRectangularWindow_MouseLeftButtonDown"
    WindowStyle="None" 
    AllowsTransparency="True" 
    Background="Transparent">
    <Canvas Width="200" Height="200" >
       <Path Stroke="DarkGray" StrokeThickness="2">
           <Path.Fill>
               <LinearGradientBrush StartPoint="0.2,0" EndPoint="0.8,1" >
                   <GradientStop Color="White"  Offset="0"></GradientStop>
                   <GradientStop Color="White"  Offset="0.45"></GradientStop>
                   <GradientStop Color="LightBlue" Offset="0.9"></GradientStop>
                   <GradientStop Color="Gray" Offset="1"></GradientStop>
               </LinearGradientBrush>
           </Path.Fill>
           <Path.Data>
               <PathGeometry>
                   <PathFigure StartPoint="40,20" IsClosed="True">
                       <LineSegment Point="160,20"></LineSegment>
                       <ArcSegment Point="180,40" Size="20,20" SweepDirection="Clockwise"></ArcSegment>
                       <LineSegment Point="180,80"></LineSegment>
                       <ArcSegment Point="160,100" Size="20,20" SweepDirection="Clockwise"></ArcSegment>
                       <LineSegment Point="90,100"></LineSegment>
                       <LineSegment Point="90,150"></LineSegment>
                       <LineSegment Point="60,100"></LineSegment>
                       <LineSegment Point="40,100"></LineSegment>
                       <ArcSegment Point="20,80" Size="20,20" SweepDirection="Clockwise"></ArcSegment>
                       <LineSegment Point="20,40"></LineSegment>
                       <ArcSegment Point="40,20" Size="20,20" SweepDirection="Clockwise"></ArcSegment>
                   </PathFigure>
               </PathGeometry>
           </Path.Data>
       </Path>
       <Label Width="200" Height="120" FontSize="15" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">Drag Me</Label>
       <Button Canvas.Left="155" Canvas.Top="30" Click="closeButtonRectangle_Click">
           <Button.Template>
               <ControlTemplate>
                   <Canvas>
                       <Rectangle Width="15" Height="15" Stroke="Black" RadiusX="3" RadiusY="3">
                           <Rectangle.Fill>
                               <SolidColorBrush x:Name="myAnimatedBrush" Color="Red" />
                           </Rectangle.Fill>
                       </Rectangle>
                       <Line X1="3" Y1="3" X2="12" Y2="12" Stroke="White" StrokeThickness="2"></Line>
                       <Line X1="12" Y1="3" X2="3" Y2="12" Stroke="White" StrokeThickness="2"></Line>
                   </Canvas>
               </ControlTemplate>
           </Button.Template>
       </Button>
   </Canvas>
</Window>

代码文件:

using System.Windows;
using System.Windows.Input;

namespace WpfWindow
{
    public partial class CustomerWindow : Window
    {
        public CustomerWindow()
        {
           InitializeComponent();
       }

       void NonRectangularWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
       {
           this.DragMove();
       }

       void closeButtonRectangle_Click(object sender, RoutedEventArgs e)
       {
           this.Close();
       }
   }
}

WPF布局管理之StackPanel、WrapPanel、DockPanel

StackPanel

StackPanel 是以堆叠的方式显示其中的控件

WrapPanel

WrapPanel 是以流的形式由左到右,由上到下显示控件,其功能类似于 Java AWT 布局中的 FlowLayout。

DockPanel

以上、下、左、右、中为基本结构的布局方式,类似于 Java AWT 中的 BorderLayout。

但与 BorderLayout 不同的是,每一个区域都可以同时放置多个控件,在同一区域放置的多个控件才有的布局方式为 StackPanel 方式。

WPF布局管理之Grid、UniformGrid

Grid

Grid 是以表格形式组织控件的一种布局方式,与 Java AWT 中的 GridLayout 类似,但是区别在于

  • WPF 中的 Grid 的每一个单元格中可以放置多个控件,但控件可能会层叠在一起。
  • WPF 中的 Grid 支持单元格的合并,类似于 HTML 中的 table td 中的 rowspan 和 colspan 。
  • Grid 中的行和列可以自定义高度。设置高度时可以采用两种写法
    1. Height = "60":表示固定的高度
    2. Height = "60*":表示"加权"的高度,在调整窗体大小时,值会按窗体的大小改变的比例进行缩放。

使用GridSplit分割

可以使用GridSplit控件结合Grid控件实现类似于Windows应用程序中SplitContainer的功能

UniformGrid

UniformGrid 控件为控件提供了一种简化的网格布局。当控件添加到 UniformGrid 时,它们会排列在一个网格模式中,该网格模式会自动调整以使控件之间的距离保持均匀。单元格的数目将进行调整,以适应控件的数目。例如,如果四个控件添加到 UniformGrid 中,它们将安排在包含四个单元格的网格中。

在使用UniformGrid的时候:

  • 各单元格的大小完全相同
  • 单元格的数量取决于放入的控件的数量,且单元格一定是行、列数相同的,即11、22、33、44…的单元格分布

WPF布局管理之Canvas、InkCanvas

Canvas

在WPF中子元素的绝对定位的布局控件

  • 其子元素使用Width、Height定义元素的宽度和高度
  • 使用Convas.Left(Convas.Right)、Convas.Top(Convas.Bottom)定义与Convas容器的相对位置
  • 如果同时存在Convas.Left和Convas.Right、Convas.Top和Convas.Bottom,则Convas.Left、Convas.Top优先生效

    <Canvas>
        <Button Canvas.Left="10" Canvas.Top="10" Height="23" Width="75">LT</Button>
        <Button Canvas.Right="10" Canvas.Top="10" Height="23" Width="75">RT</Button>
        <Button Canvas.Left="10" Canvas.Bottom="10" Height="23" Width="75">LB</Button>
        <Button Canvas.Right="10" Canvas.Bottom="10" Height="23" Width="75">RB</Button>
    </Canvas>
    

在调整窗体大小时,LT与左、上距离保持不变;RT与右、上距离保持不变;LB与左、下距离保持不变;RB与右、下距离保持不变。使用Canvas不能简单地实现Windows应用程序中Acho的功能。

InkCanvas

在WPF中实现允许使用墨迹的控件

<Window x:Class="WpfApplication1.InkCanvasWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="InkCanvasWindow" Height="300" Width="300">
    <InkCanvas>
        <InkCanvas.DefaultDrawingAttributes>
            <DrawingAttributes Color="Red" />
        </InkCanvas.DefaultDrawingAttributes>
        <Image Width="155" Height="155" InkCanvas.Left="10" InkCanvas.Top="10" 
                  Source="/WpfApplication1;component/123.jpg"/>
    </InkCanvas>
</Window>

记于 2013/8/2 13:55:56
常伟华 Changweihua
changweihua@outlook.com

知识共享许可协议
《WPF and Silverlight 学习笔记1》 常伟华 创作。
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议 | 3.0 中国大陆许可协议进行许可。

站内公告

A PHP Error was encountered

Severity: Core Warning

Message: PHP Startup: zip: Unable to initialize module Module compiled with module API=20060613 PHP compiled with module API=20090626 These options need to match

Filename: Unknown

Line Number: 0

Backtrace: