WPF 基础

XAML

XAML是基于XML的,它是WPF外在的表现形式。

XAML是一个纯粹的标记语言,这也就意味着某个元素要实现一个事件的处理时,需要在该元素中通过特定的属性来指定相应的事件处理方法名,

而真正的事件处理逻辑你可以通过C#或者VB.NET语言进行实现(代码后置方式),我们是没有办法通过XAML来编写相应的事件处理逻辑的。

在XAML中,每个属性都是和某个WPF类的属性相对应的,而且所有的元素名称都和WPF中定义的类名称相匹配。

在XAML文件中,可使用<x:code>元素,并将所有代码通过内联方式都封装在<![CDATA[...]]>标签中,以确保分析器不会对其中的代码进行解析。

<Button Name="button1" Click="Clicked">Click Me!</Button>
<x:Code>
<![CDATA[ void Clicked(object sender, RoutedEventArgs e) { button1.Content = "Hello World"; } ]]>
</x:Code>

命名空间

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  

默认引用WPF必须的dll:  PesentationCore/PresentationFramework/System.Xaml/WindowBase

所有该命名空间下的对象元素都不需要使用前缀,如 <window/><Grid/><Button/>

 

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 如:x:Class/x:Key/x:Name/x:Static/x:Type/x:Code ...

 其中 x:Key 最为常用,在同一个资源块中,所有 x:Key不能重名,因为它们同属于ResourceDirtionary

 

x:Class="WpfApplication1.MainWindow"  

标记部份由 XAML 编译后,作为后台代码类 MainWindow.xaml.cs 的一部份,是 partial 的关系

 

xmlns:sys="clr-namespace:System;assembly=mscorlib" 

引用系统DLL命名空间,如: 作为全局变量

<Window.Resources>
        <sys:String x:Key="name">Apple</sys:String>
</Window.Resources>

<Button Content="{StaticResource ResourceKey=name}"></Button> === <Button Content="Apple"></Button>

 

xmlns:viewmodel="clr-namespace:MyWPF.ViewModels"

引用用户DLL命名空间

 

依赖属性

WPF界面控件中的属性,都可以称作是依赖属性,通过依赖属性,我们能够实现viewModel与界面元素属性之间进行绑定。

依赖属性所属类必须继承或间接继承自:System.Windows.DependencyObject类

 

触发器(属性、多条件、数据和事件触发器)

属性触发器: Trgger的 Property 来自所检查元素(TargetType所指)的依赖属性, 当其Value 为指定的值时, 驱动Setter变化

<Button MinWidth="75" Margin="10" Content="Submit">
                <Button.Style>
                    <Style TargetType="{x:Type Button}">
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="Blue" />
                            </Trigger>

        
                        </Style.Triggers>
                    </Style>
                </Button.Style>
</Button>

<TextBox TextWrapping="Wrap" Margin="5" Width="100">
                <TextBox.Style>
                    <Style TargetType="TextBox">
                        <Style.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Text" Value="Red"/>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" Value="Red"/>
                            </MultiTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBox.Style>
</TextBox>

<TextBox MinWidth="50" TextWrapping="Wrap" Margin="5">
                <TextBox.Style>
                    <Style TargetType="TextBox">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="type me">
                                <Setter Property="Background" Value="Aqua"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBox.Style>
</TextBox>

<Window.Resources>
        <Style TargetType="Button">
            <Style.Triggers>
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0.1"  Duration="0:0:3"></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
</Window.Resources>
<Grid>
        <Button Content="Submit"></Button>
</Grid>

数据触发器: DataTrgger的 Property 来自DataContext所定义的非依赖属性, 当其Value 为指定的值时, 驱动Setter变化  

 <Style TargetType="dxg:GridControl">
            <Style.Triggers>
                <DataTrigger Binding="{Binding CurrentView}" Value="AView">
                    <Setter Property="View" Value="BView"/>
                </DataTrigger>
            </Style.Triggers>
 </Style>
...
 <Button Content="{Binding CurrentView}" Grid.Row="0" Command="{Binding ChangeCurrentView}"/>
  <dxg:GridControl Grid.Row="1" 
                         DataSource="{Binding XXX}"
                         AutoPopulateColumns="True" >
  </dxg:GridControl>

资源

xxx.Resources: 应用/窗体/控件级别的

ResourceDictionary: 文件级别的

引用资源方式:StaticResource/DynamicResource, 主要区别:一个是非运行时获取/一个是运行时获取(主要考虑需要在运行时更改资源值时,才使用)

资源是从下向上查找,如:

<StackPanel>
    <StackPanel.Resources>
            <sys:Double x:Key="msize">  <!--同名,由于不属于同一资源块-->
            12
        </sys:Double>
    </StackPanel.Resources>
    <Button FontSize="{DynamicResource ResourceKey= msize}">
            <Button.Resources>
                <sys:Double x:Key="msize"> <!--同名,由于不属于同一资源块-->
                    20
                </sys:Double>
            </Button.Resources>
            font size is 20
        </Button>
    <Button FontSize="{DynamicResource ResourceKey= msize}">font size is 12</Button>
</StackPanel>

 

大括号转义写法:

<TextBlock Text="{}{Hello World!}" />

 

Binding

是源数据(属性/控件/集合/XML等等)在目标对象(UI Element)展现出的桥梁

 

与属性的绑定

<TextBox Text="{Binding Name}" />

与对象元素的绑定,如

<TextBox x:Name="txtName" />
<Label Content="{Binding ElementName=txtName, Path=Text}" />

与数据上下文对象绑定

class Person{

  public string Name{get;set;}

  public int Age{get;set;}

}

this.DataContext=new Person{Name="Apple", Age=20};

<TextBox Text="{Binding Path=Name}"></TextBox>
<TextBox Text="{Binding Path=Age}"></TextBox>

 

 <TreeView ItemsSource="{Binding Source={StaticResource dataset}}">

......

主要用于同名无法确定的时候,可进行相对查找源:在 AncestorLevel和AncestorType 两参数进行设置

 

<TextBox Text="{Binding RelativeSource={RelativeSource
Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UIElement}}, Path=Name}">
</TextBox>

Binding.Mode

OneWay 源更新时,目标也更新
TwoWay 源更新时目标也更新,或者目标更新时同时更新源 (属性只读时,不可使用)
OneTime
目标只从源获取一次数据,之后互不影响
OneWayToSource 目标更新时, 源也更新

 

  • 对源数据更新了,要自动影响目标对象展现, 则源灵气必须实现 INotifyPropertyChanged 接口.
  • 与集合的绑定, 则需要这样: ObservableCollection<T> xxx

 

命令

命令: 通过实现 ICommand, 包括: Execute/CanExecute/CanExecuteChanged

命令源: 调用命令的对象, 通过实现 ICommandSource, 包括: Command/CommandTarget/CommandParameter

命令目标: 命令所作用的对象, 在 CommandTarget 中体现

命令绑定: 命令与事件之间的桥梁

 

布局

Grid: 行列方式,通过设置 RowDefinition,ColumnDefinition

Canvas:  坐标方式, 通过设置 ZIndex, Top, Left, Bottom, Right

StackPanel:层叠方式 ,通过设置 Orientation

DockPanel:泊位方式, 结合 StackPanel,通过设置父项 DockPanel 的 Dock

WarpPanel:可换行的 StackPanel,通过设置 ItemHeight,ItemWidth

 

模板

 

 DataTemplete

用于显示 Content 的数据模板, 强调所绑定的Content以什么形式显示出来, 不影响其控件本身的外观.

通常这样来呈现:

首先在资源中定义DataTemplete, 如:

<DataTemplate DataType="{x:Type vm:XXXXXXViewModel}">
  <v:XXXXXXView />
</DataTemplate>

 然后在定义一个 ContentControl, 如:

<ContentControl Content="{Binding Path=XXXXXXViewModel}" />

这样XXXXXXViewModel将会在 <v:XXXXXXView/> 中呈现出来, 相当于把XXXXXXViewModel Binding 在 <v:XXXXXXView />中的DataContext

或者这样定义:

<ContentControl Content="{Binding Path=XXXXXXViewModel}">
    <ContentControl.Resources>
         <DataTemplate DataType="{x:Type vm:XXXXXXViewModel}">
              <v:XXXXXXView />
         </DataTemplate>
   </ContentControl.Resources>
</ContentControl>
<DataTemplate x:Key="MyTemplate" DataType="{x:Type vm:XXXXXXViewModel}">
       <v:XXXXXXView />
</DataTemplate>

<ListBox  ItemTemplate="{StaticResource  MyTemplate}" />

或其他具有 ItemTemplate 的元素

 

ControlTemplate

用于设置控件具体的样式, 定义控件外观的模板, 跟内空没关系.

 

ItemsPanelTemplate

 

application相关触发的主要事件有

  1. startup - 应用程序启动

  2. exit - 应用程序关闭。

  3. activated - 应用程序获得焦点时触发,也就是成为前台程序。

  4. deactivated - 应用程序失去焦点时,也就是不再是前台程序时。

  5. dispatcherunhandledexception - 当一个异常被抛出时,你可以选择处理或者是抛出该异常。

  6. sessionending - windows正在关闭时,无论是注销还是关机,都会触发该事件。你可以选择取消关机。

 

  你可以通过重写on[eventname]方法来添加对事件的处理, 如  onstartup。

 

window startup时会触发的事件有

  • initialized - main window is being created
  • isvisiblechanged - isvisible property set to true
  • sizechanged - size property set to size of window
  • layoutupdated - window layout changes
  • sourceinitialized - window is attached to win32 window handle
  • activated - window becomes foreground window
  • previewgotkeyboardfocus - window getting focus
  • iskeyboardfocuswithinchanged - iskeyboardfocuswithin property set to true
  • iskeyboardfocusedchanged - iskeyboardfocused property set to true
  • gotkeyboardfocus - window now has keyboard focus
  • layoutupdated - window layout changes
  • loaded - window is now laid out, fully rendered
  • contentrendered - all window content has been rendered

window shutdown时触发的事件有:

  • closing - window is going to close
  • isvisiblechanged - isvisible property set to false
  • deactivated - window becomes background window
  • iskeyboardfocuswithinchanged - iskeyboardfocuswithin property set to false
  • iskeyboardfocusedchanged - iskeyboardfocused property set to false
  • lostkeyboardfocus - window no longer has keyboard focus
  • closed - window is closing

 

 

posted @ 2013-03-19 09:39  Yu  阅读(379)  评论(0编辑  收藏  举报