zoukankan      html  css  js  c++  java
  • 【转载】学习WPF,转向移动互联网(windows phone && windows 8 )开发(下) 天高地厚

    一、      绑定(Binding )

    定义                                                        

    l         绑定是应用程序UI与业务逻辑之间建立连接的过程。

    l         四个组件,绑定目标对象、目标属性、绑定源、绑定值的路径。

    目标属性必须是依赖属性。建立绑定时,是将绑定目标绑定到绑定源,例如:使用数据绑定在Datagrid显示xml数据,就是将Datagrid绑定到xml数据。

    绑定的数据流方向

    1、  OneWay 绑定源属性值更改自动更新目标属性,目标属性值更改不会传播给绑定源属性(源—>UI)。

    2、  TwoWay 绑定源更改更新目标属性,目标属性更改更新绑定源(源<>UI)。

    3、  OneWayToSource OneWay 绑定相反;它在目标属性更改时更新源属性。一个示例方案是您只需要从 UI 重新计算源值的情况(UI>源)。。

    4、  OneTime该绑定会导致源属性初始化目标属性,但不传播后续更改。此绑定类型实质上是 OneWay 绑定的简化形式,在源值不更改的情况下可以提供更好的性能(源—>UI(一次性))。

    l         源值改变的时机由UpdateSourceTrigger控制,PropertyChanged即时改变,LostFocus目标对象失去焦点时改变,Explicit当应用程序调用 UpdateSource 时改变(eg:提交时改变)。

    指定绑定源的方法                                                    

    u       绑定到另一个元素的某个属性值。EgTextBoxAText目标数属性绑定 TextboxB对象,绑定值的路径Path=Text。使用ElementName绑定方法。

    <TextBox Name="TextBoxA" ></TextBox>

    <TextBox Name="TextBoxB" Text="{Binding ElementName=TextBoxA,        Path=Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">

    </TextBox>

    u       Source 属性是一种可以显式设置 Binding 的源和重写继承的数据上下文的方式。

    Eg:现有一个string类型PersonName属性的Person对象。

    <Window.Resources>

                    <src:Person x:Key="myDataSource" PersonName="Joe"/>

               </Window.Resources>

               <TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=PersonName}"/>

    u       RelativeSource。可以为目标对象指定绑定到其自身的其他属性,或者是其父元素的属性。在创建数据模板和控件模板、样式时使用。

    Eg:在Datagrid的表格鼠标悬停时,使用Tooltip放大其表格的内容。

    <Style TargetType="{x:Type uc:DataGridCell}">

             <Setter Property="ToolTip" Value="{Binding Content.Text, RelativeSource={RelativeSource Self}}"/>

             </Style>

    u       DataContext。将多个元素的属性绑定到同一个数据源时使用,在父元素的中设置,子元素继承之。

    数据转换(默认转化器和自定义转换器)                               

    集成接口IValueConverter实现ConvertConvertBack方法。

      

    View Code
     1  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     2 
     3         {
     4 
     5             int index = (int)value;
     6 
     7             string result = null;
     8 
     9             switch (index)
    10 
    11             {
    12 
    13                 case 1:
    14 
    15                     result = "星期一";
    16 
    17                     break;
    18 
    19                 case 2:
    20 
    21                     result = "星期二";
    22 
    23                     break;
    24 
    25             }
    26 
    27             return result;
    28 
    29         }
    30 
    31         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    32 
    33         {
    34 
    35             string index = (string)value;
    36 
    37             int result = -1;
    38 
    39             switch (index)
    40 
    41             {
    42 
    43                 case "星期一":
    44 
    45                     result = 1;
    46 
    47                     break;
    48 
    49                 case "星期二":
    50 
    51                     result = 2;
    52 
    53                     break;
    54 
    55             }
    56 
    57             return result;
    58 
    59         }

     

    绑定到集合                                                         

    u       应使用ItemSource属性,ModeOneWay

    u       设置动态绑定,集合的删除、插入操作可以自动更新UI,那集合必须实现INotifyPropertyChanged接口(此接口公开一个PropertyChangedEventHandler的事件,只要基础集合发生更改,都应该引发该事件)。WPF 提供 ObservableCollection<T>类,它是公开 INotifyCollectionChanged 接口的数据集合的内置实现。

    u       集合视图

    一旦 ItemsControl 绑定到数据集合,您可能希望对数据进行排序、筛选或分组。若要执行此操作,可以使用集合视图,这是实现 ICollectionView 接口的类。

    方法:定义个集合视图,在此视图上进行排序、筛选、分组的操作。绑定的目标对象绑定其集合视图。

    XAML:

    <!—资源-->

    <Window.Resources>

              <!—定义集合视图,大大提高集合的操作性-->

            <CollectionViewSource Source="{Binding Source={x:Static Application.Current}[l1] , Path=Employee}" [l2] 

                                   x:Key="view"></CollectionViewSource>

           </Window.Resources>

    <Grid>

            <Grid.RowDefinitions>

                <RowDefinition/>

                <RowDefinition/>

            </Grid.RowDefinitions>

            <DataGrid Name="TestDg" AutoGenerateColumns="False" Grid.Row="0"

                      ItemsSource="{Binding Source={StaticResource view}[l3] }" IsReadOnly="True" >

                <DataGrid.Columns>

                  <DataGridTextColumn Header="职工姓名" Binding="{Binding S_STUFFNAME}"></DataGridTextColumn>

                    <DataGridTextColumn Header="职工性别" Binding="{Binding Converter={StaticResource sexConverter}}"></DataGridTextColumn>

                </DataGrid.Columns>

            </DataGrid>

            <StackPanel Grid.Row="1" Orientation="Vertical">

                <CheckBox Name="sort" Checked="sort_Checked" Unchecked="sort_Unchecked"  Content="sort"></CheckBox>

                <CheckBox Name="group" Checked="group_Checked" Unchecked="group_Unchecked"  Content="group"></CheckBox>[l4] 

            </StackPanel>

            </Grid>

    Code

     

    View Code
      1 /// <summary>
      2 
      3         /// 集合视图
      4 
      5         /// </summary>
      6 
      7         CollectionViewSource datagridview;
      8 
      9         public MainWindow()
     10 
     11         {
     12 
     13             InitializeComponent();
     14 
     15             //获取XAML的view
     16 
     17             datagridview = (CollectionViewSource)(this.Resources["view"]);
     18 
     19             ObservableCollection<Employee> listEmy = new ObservableCollection<Employee> 
     20 
     21             {
     22 
     23                 new Employee(){ RowNum=1, S_STUFFCODE="00587000123", S_STUFFNAME="张三", S_SEX="1"},
     24 
     25 new Employee(){RowNum=2,S_STUFFCODE="00587000124",S_STUFFNAME="李四",S_SEX="1"},};
     26 
     27             //设置视图的Source
     28 
     29             datagridview.Source = listEmy;
     30 
     31          }
     32 
     33         /// <summary>
     34 
     35         /// 排序
     36 
     37         /// </summary>
     38 
     39         /// <param name="sender"></param>
     40 
     41         /// <param name="e"></param>
     42 
     43         private void sort_Checked(object sender, RoutedEventArgs e)
     44 
     45         {
     46 
     47         datagridview.SortDescriptions.Add(
     48 
     49                 new SortDescription("S_STUFFCODE", ListSortDirection.Descending));
     50 
     51         datagridview.SortDescriptions.Add(
     52 
     53               new SortDescription("S_STUFFNAME", ListSortDirection.Descending));
     54 
     55         }
     56 
     57         /// <summary>
     58 
     59         /// 清除排序
     60 
     61         /// </summary>
     62 
     63         /// <param name="sender"></param>
     64 
     65         /// <param name="e"></param>
     66 
     67         private void sort_Unchecked(object sender, RoutedEventArgs e)
     68 
     69         {
     70 
     71             datagridview.SortDescriptions.Clear();
     72 
     73         }
     74 
     75         /// <summary>
     76 
     77         /// 分组
     78 
     79         /// </summary>
     80 
     81         /// <param name="sender"></param>
     82 
     83         /// <param name="e"></param>
     84 
     85         private void group_Checked(object sender, RoutedEventArgs e)
     86 
     87         {
     88 
     89             PropertyGroupDescription group = new PropertyGroupDescription();
     90 
     91             group.PropertyName = "S_SEX";
     92 
     93             datagridview.GroupDescriptions.Add(group);
     94 
     95         }
     96 
     97         /// <summary>
     98 
     99         /// 清除分组
    100 
    101         /// </summary>
    102 
    103         /// <param name="sender"></param>
    104 
    105         /// <param name="e"></param>
    106 
    107         private void group_Unchecked(object sender, RoutedEventArgs e)
    108 
    109         {
    110 
    111             datagridview.GroupDescriptions.Clear();
    112 
    113         }

     

    数据验证ValidationRuleSystem.Windows.Controls                     

    接受用户输入的大多数应用程序都需要具有验证逻辑,以确保用户输入了需要的信息。验证检查可以基于类型、范围、格式或其他应用程序特定的要求。

    WPF内置的ValidationRule对象                                      

    u      ExceptionValidationRule 检查在更新绑定源属性的过程中引发的异常

    <StackPanel Grid.Row="2" Name="stk">

                <TextBox Name="StartPriceEntryForm"  Height="20" Width="150" DataContext="{Binding}"[l5] >

                    <TextBox.Text>

                        <Binding Path="RowNum" UpdateSourceTrigger="PropertyChanged">

                            <Binding.ValidationRules>

                                <ExceptionValidationRule />

                            </Binding.ValidationRules>

                        </Binding>[l6] 

                    </TextBox.Text>

                </TextBox>

           </StackPanel>

    Code

            Employee e = new Employee() { RowNum = 1, S_STUFFCODE = "00587000123", S_STUFFNAME = "张三", S_SEX = "1" };

            stk.DataContext = e;[l7] 

    本例子中TextBox绑定了Employee中的RowNum属性,RowNumint型,当在TextBox中输入的类型不是int类型时,就触发ExceptionValidationRule异常。

    u      DataErrorValidationRule表示一个规则,该规则检查由源对象的 IDataErrorInfo 实现所引发的错误。

            <StackPanel Name="stkData" Grid.Row="3" >

                <TextBox Height="20" Width="150" DataContext="{Binding}">

                    <TextBox.Text>

                        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">

                            <Binding.ValidationRules>

                                <DataErrorValidationRule/>

                            </Binding.ValidationRules>[l8] 

                        </Binding>

                    </TextBox.Text>

                </TextBox>

            </StackPanel>

     

    Code

     

    View Code
     1  public class Person : IDataErrorInfo[l9] 
     2 
     3     {
     4 
     5         private int age;
     6 
     7         public int Age
     8 
     9         {
    10 
    11             get { return age; }
    12 
    13             set { age = value; }
    14 
    15         }
    16 
    17         public string Error
    18 
    19         {
    20 
    21             get
    22 
    23             {
    24 
    25                 return null;
    26 
    27             }
    28 
    29         }
    30 
    31         public string this[string name]
    32 
    33         {
    34 
    35             get
    36 
    37             {
    38 
    39                 string result = null;
    40 
    41  
    42 
    43                 if (name == "Age")
    44 
    45                 {
    46 
    47                     if (this.age < 0 || this.age > 150)
    48 
    49                     {
    50 
    51                     result = "Age must not be less than 0 or greater than 150.";
    52 
    53                     }
    54 
    55                 }
    56 
    57                 return result;
    58 
    59             }
    60 
    61         }
    62 
    63 }

     

        自定义绑定验证                                                           

    通过从ValidationRules类派生和实现Validate方法来创建自己的验证。

    u      定义验证规则

     

    View Code
     1  public class Validation : ValidationRule
     2 
     3          {
     4 
     5         public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
     6 
     7         {
     8 
     9             int age = Convert.ToInt32(value);
    10 
    11             if (age > 150)
    12 
    13             {
    14 
    15                 return new ValidationResult(false, "数字过大!");
    16 
    17             }
    18 
    19  
    20 
    21             return new ValidationResult(true, null);
    22 
    23         }
    24 
    25       }

     

    u      XAML中绑定

     <StackPanel Name="stkData" Grid.Row="3" >

                <TextBox Height="20" Width="150" DataContext="{Binding}">

                    <TextBox.Text>

                        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">

                            <Binding.ValidationRules>

                                <local:Validation></local:Validation>

                            </Binding.ValidationRules>[l10] 

                        </Binding>

                    </TextBox.Text>

                </TextBox>

            </StackPanel>

    l         数据验证错误显示模板

    当输入值无效时,需要在UI反馈用户。提供反馈的方法是将Validation.ErrorTempate附加属性中加入自定义的ControlTempate

       <ControlTemplate x:Key="validationTemplate">

             <DockPanel>

                 <TextBlock Foreground="Red" FontSize="20">!</TextBlock>

                  <AdornedElementPlaceholder/>

             </DockPanel>

       </ControlTemplate>

    <ControlTemplate x:Key="validationTemplate">

       <DockPanel>

          <AdornedElementPlaceholder Name="MyAdorner"/>

           <TextBox Foreground="Red"  IsEnabled="False"

                   Text="{Binding ElementName=MyAdorner,

    Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">

    </TextBox>

        </DockPanel>

    </ControlTemplate>

     

      二、      WPF和之前的技术交互(WPF/WinForms)

     

    System.Windows.Forms.Integration 命名空间提供实现常见互操作方案的类。 实现互操作功能的两个关键类是 WindowsFormsHostElementHost

    l         WPF 中承载Windows Forms窗体控件

    l         方法:

      在wpf上承载Windows Forms控件,需要使用WindowsFormsHost。(添加System.Windows.Forms和WindowsFormsIntegration程序集的引用。

    Eg:<Grid>

            <WindowsFormsHost >

                <wf:MaskedTextBox Height="20" BackColor="Red" Width="20" ></wf:MaskedTextBox>

            </WindowsFormsHost>

    </Grid>

    l         限制

    u Windows Forms控件不能调整大小,或者只能调整为特定的尺寸。

    u Windows Forms控件不能旋转和扭曲。

    l          Windows Forms中使用Wpf

    l         方法:

    Windows Forms中使用Wpf,需要使用ElementHost。

    三、      怎样布局一个漂亮的UI的?

    l         项目总结

    u 已有控件布局。界面统一风格(使用Blend绘出界面背景),使用样式、模板改变控件外观。

    Eg:datagrid treeview

    u 通过使用Blend软件,绘制自定义控件。

    l         布局控件

    l         Canvas

    Canvas比较简单,只是一个存储元素的容器,它不会自动调整内部元素的排列及大小。不指定元素位置,元素将默认显示在画布的左上方。Canvas的主要用途是用来画图。Canvas默认不会自动裁减超过自身范围的内容,即溢出的内容会显示在Canvas外面,这是因为默认 ClipToBounds="False";我们可以通过设置ClipToBounds="True来裁剪多出的内

    l         StackPanel

    StackPanel就是将子元素按照堆栈的形式一一排列,通过设置面板的Orientation属性设置了两种排列方式:横排(Horizontal默认的)和竖排(Vertical)。

    l         WrapPanel

    WrapPanel是一个非常简单的面板,从左至右按顺序位置定位子元素,如果排满断开至下一行。后续排序按照从上至下或从右至左的顺序进行。WrapPanel面板也提供了Orientation属性设置排列方式,这跟上面的StackPanel基本相似。不同的是WrapPanel会根据内容自动换行。

    l         DockPanel

    DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列。停靠面板其实就是在WinForm类似于Dock属性的元素。(随窗体缩放、扩大)

    l         Border

    Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件(这个子控件又可以包含多个子控件)。Border 的几个重要属性:Background:用用一个 Brush 对象来绘制背景;BorderBrush:用一个Brush 对象来绘制边框;BorderThickness:此属性设置 Border 边框的大小;CornerRadius:此属性设置 Border 的每一个角圆的半径;Padding:r属性设置 Border 里的内容与边框的之间的间隔。


  • 相关阅读:
    根据模板自动生成数据
    CSV to XLSX (专用)
    释放用完的Excel COM组件
    配置文件的力量
    字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别)
    将结果中的省略号内容全部输出
    Powershell变量的类型
    一些用过的C#类库收集
    运算符
    特殊运算符
  • 原文地址:https://www.cnblogs.com/net2012/p/2977527.html
Copyright © 2011-2022 走看看