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 里的内容与边框的之间的间隔。


  • 相关阅读:
    LeetCode 81 Search in Rotated Sorted Array II(循环有序数组中的查找问题)
    LeetCode 80 Remove Duplicates from Sorted Array II(移除数组中出现两次以上的元素)
    LeetCode 79 Word Search(单词查找)
    LeetCode 78 Subsets (所有子集)
    LeetCode 77 Combinations(排列组合)
    LeetCode 50 Pow(x, n) (实现幂运算)
    LeetCode 49 Group Anagrams(字符串分组)
    LeetCode 48 Rotate Image(2D图像旋转问题)
    LeetCode 47 Permutations II(全排列)
    LeetCode 46 Permutations(全排列问题)
  • 原文地址:https://www.cnblogs.com/net2012/p/2977527.html
Copyright © 2011-2022 走看看