zoukankan      html  css  js  c++  java
  • 8天入门wpf—— 第五天 数据绑定

         

           在webform中,如果提到“绑定”二字,相信大家都不会陌生,绑定,让我们的代码更加的简洁优美,在wpf中也存在各种神马的绑定,

    当然使用上都是行隔理不隔。

         

    一: 控件到控件的绑定

         既然是绑定,那么肯定就有”源对象“和”目标对象“两种状态实体,从图的角度上来说存在三种状态:

    确实在wpf中存在这三种模式的对应方式,

    1:OneWay

        正如图A所说,Source影响着Target,但是Target却影响不到Source。

    2:OneWayToSource

       也正如图B中所表述的一样,Target影响Source,而Source却影响不到Target。

    3:TwoWay

       这个也就相当于无向图的边,Source与Target相互影响。

    4:OneTime

       在OneWay的基础上延伸了一个OneTime,仅绑定一次。如果大家属性Jquery中的one函数我想就可以不用表述了。

     1 <Window x:Class="WpfApplication1.MainWindow"
     2          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4          Title="MainWindow" Height="350" Width="525">
     5     <Canvas>
     6         <ScrollBar Height="24" Name="scrollBar1" Width="237" Orientation="Horizontal" Canvas.Left="103" Canvas.Top="51"  Minimum="1" Maximum="100" SmallChange="1" />
     7         <Label Canvas.Left="41" Canvas.Top="121" Content="OneWay" Height="28" Name="label1" />
     8         <TextBox Canvas.Left="165" Canvas.Top="121" Height="23"
     9                  Text="{Binding ElementName=scrollBar1, Path=Value, Mode=OneWay}"
    10                  Name="textBox1" Width="120" />
    11         <Label Canvas.Left="41" Canvas.Top="160" Content="OneWayToSource" Height="28" Name="label2" />
    12         <TextBox Canvas.Left="165" Canvas.Top="160" Height="23"
    13                    Text="{Binding ElementName=scrollBar1, Path=Value, Mode=OneWayToSource}"
    14                  Name="textBox2" Width="120" />
    15         <Label Canvas.Left="41" Canvas.Top="202" Content="TwoWay" Height="28" Name="label3" />
    16         <TextBox Canvas.Left="165" Canvas.Top="202" Height="23"
    17                    Text="{Binding ElementName=scrollBar1, Path=Value, Mode=TwoWay}"
    18                  Name="textBox3" Width="120" />
    19         <Label Canvas.Left="41" Canvas.Top="231" Content="OneTime" Height="28" Name="label4" />
    20         <TextBox Canvas.Left="165" Canvas.Top="231" Height="23" 
    21                    Text="{Binding ElementName=scrollBar1, Path=Value, Mode=OneTime}"
    22                  Name="textBox4" Width="120" />
    23     </Canvas>
    24 </Window>

    最终的结果,还是大家自己拖拖滚动条吧,有图有真相。

    二:.net对象与控件的绑定

         这种绑定还是经常使用的,在WebForm中我们常用的Eval就是此种绑定,因为俺从数据库里好不容易捞了点数据总要呈现在UI上面吧,

    好,不多说,上代码说话。

     1 <Window x:Class="WpfApplication3.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:local="clr-namespace:WpfApplication3"
     5         Title="MainWindow" Height="350" Width="525">
     6     <Grid>
     7         <ListView  Height="287" HorizontalAlignment="Left" Margin="62,12,0,0" Name="listView1" VerticalAlignment="Top" Width="331">
     8             <ListView.View>
     9                 <GridView>
    10                     <GridView.Columns>
    11                         <GridViewColumn Header="姓名"  DisplayMemberBinding="{Binding Name}"/>
    12                         <GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Age}"/>
    13                     </GridView.Columns>
    14                 </GridView>
    15             </ListView.View>
    16         </ListView>
    17     </Grid>
    18 </Window>

    首先谢天谢地,我们的数据出来了,好,现在我们有需求了,我现在需要给奇偶行填充不同底色,并且age=22的这行数据标红,那在wpf中该

    怎么做呢?我们依稀的记得在webform中我们会在“行事件”上做手脚,在数据的绑定上wpf给我们提供了一个口子,也就是在绑定时可以插入自

    己的”事件处理代码“,但必须要继承自IValueConverter。

     1 <Window x:Class="WpfApplication3.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:local="clr-namespace:WpfApplication3"
     5         Title="MainWindow" Height="350" Width="525">
     6     <Window.Resources>
     7         <local:ColorConvert x:Key="myConvert"/>
     8         <Style x:Key="item" TargetType="{x:Type ListViewItem}">
     9             <Setter Property="Background">
    10                 <Setter.Value>
    11                     <Binding RelativeSource="{RelativeSource Self}" 
    12 Converter="{StaticResource myConvert}"/>
    13                 </Setter.Value>
    14             </Setter>
    15         </Style>
    16     </Window.Resources>
    17     <Grid>
    18         <ListView ItemContainerStyle="{StaticResource ResourceKey=item}" Height="287" HorizontalAlignment="Left" Margin="62,12,0,0" Name="listView1" VerticalAlignment="Top" Width="331">
    19             <ListView.View>
    20                 <GridView>
    21                     <GridView.Columns>
    22                         <GridViewColumn Header="姓名"  DisplayMemberBinding="{Binding Name}"/>
    23                         <GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Age}"/>
    24                     </GridView.Columns>
    25                 </GridView>
    26             </ListView.View>
    27         </ListView>
    28     </Grid>
    29 </Window>
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Windows;
     6 using System.Windows.Controls;
     7 using System.Windows.Data;
     8 using System.Windows.Documents;
     9 using System.Windows.Input;
    10 using System.Windows.Media;
    11 using System.Windows.Media.Imaging;
    12 using System.Windows.Navigation;
    13 using System.Windows.Shapes;
    14 
    15 namespace WpfApplication3
    16 {
    17     /// <summary>
    18     /// MainWindow.xaml 的交互逻辑
    19     /// </summary>
    20     public partial class MainWindow : Window
    21     {
    22         public MainWindow()
    23         {
    24             InitializeComponent();
    25 
    26             List<Student> list = new List<Student>();
    27 
    28             for (int i = 20; i < 30; i++)
    29             {
    30                 list.Add(new Student() { Name = "hxc" + i, Age = i });
    31             }
    32 
    33             listView1.ItemsSource = list;
    34         }
    35     }
    36 
    37     public class ColorConvert : IValueConverter
    38     {
    39         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    40         {
    41             //这里的value既为当前的行对象
    42             var item = value as ListViewItem;
    43 
    44             //获取当前的item在当前的Listview中的位置
    45             var view = ItemsControl.ItemsControlFromItemContainer(item) as ListView;
    46 
    47             var index = view.ItemContainerGenerator.IndexFromContainer(item);
    48 
    49             //当Age=22是红色标示
    50             if ((view.Items[index] as Student).Age ==22)
    51                 return Brushes.Red;
    52 
    53             if (index % 2 == 0)
    54                 return Brushes.Pink;
    55             else
    56                 return Brushes.Blue;
    57         }
    58 
    59         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    60         {
    61             return null;
    62         }
    63     }
    64 
    65 
    66     public class Student
    67     {
    68         public string Name { get; set; }
    69 
    70         public int Age { get; set; }
    71     }
    72 }

    快看,效果出来了,这里要稍微解释下IValueConverter的使用步骤:

    ①:自定义一个类继承自IValueConverter,其中Convert方法的value 为绑定参数,parameter参数为绑定参数的附带值。

    1   public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    ②:我们需要在xaml中引用并写入资源。

     1   <Window.Resources>
     2         <local:ColorConvert x:Key="myConvert"/>
     3         <Style x:Key="item" TargetType="{x:Type ListViewItem}">
     4             <Setter Property="Background">
     5                 <Setter.Value>
     6                     <Binding RelativeSource="{RelativeSource Self}" 
     7 Converter="{StaticResource myConvert}"/>
     8                 </Setter.Value>
     9             </Setter>
    10         </Style>
    11     </Window.Resources>

    ③:最后也就是在Binding中使用Convert,wpf在绑定数据的时候会自动调用我们自定义的myConvert方法。

     1   <Window.Resources>
     2         <local:ColorConvert x:Key="myConvert"/>
     3         <Style x:Key="item" TargetType="{x:Type ListViewItem}">
     4             <Setter Property="Background">
     5                 <Setter.Value>
     6                     <Binding RelativeSource="{RelativeSource Self}" 
     7 Converter="{StaticResource myConvert}"/>
     8                 </Setter.Value>
     9             </Setter>
    10         </Style>
    11     </Window.Resources>

    三: .net方法与控件的绑定

        在做wpf时,有时我们需要在xaml中绑定.net中的方法,当然这在实际开发中也是很常用的,不过方法必要由ObjectDataProvider来封装。

     1 <Window x:Class="WpfApplication5.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4         xmlns:local="clr-namespace:WpfApplication5"
     5         xmlns:sys="clr-namespace:System;assembly=mscorlib"
     6         Title="MainWindow" Height="350" Width="525">
     7     <Window.Resources>
     8         <ObjectDataProvider x:Key="Test" ObjectType="{x:Type local:Student}" MethodName="GetName">
     9         </ObjectDataProvider>
    10     </Window.Resources>
    11     <Grid>
    12         <TextBlock Text="{Binding Source={StaticResource ResourceKey=Test}, Mode=OneWay}"/>
    13     </Grid>
    14 </Window>
     1 namespace WpfApplication5
     2 {
     3     /// <summary>
     4     /// MainWindow.xaml 的交互逻辑
     5     /// </summary>
     6     public partial class MainWindow : Window
     7     {
     8         public MainWindow()
     9         {
    10             InitializeComponent();
    11         }
    12     }
    13 
    14     public class Student
    15     {
    16         //前台要引用的方法
    17         public string GetName()
    18         {
    19             return "一线码农";
    20         }
    21     }
    22 }

    四:wpf中的验证

        我们知道不管在什么体系架构中都有属于自己的一套验证体系,比如webform中的验证控件,mvc中的特性验证,当然wpf也是有的,为了

    验证的灵活性,实际开发中我们用的比较多的还是”自定义验证“,其实只需要实现ValidationRule接口就行了,然后写上自定义的验证逻辑。

     1 <Window x:Class="WpfApplication4.MainWindow"
     2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     4        xmlns:local="clr-namespace:WpfApplication4"
     5         Title="MainWindow" Height="350" Width="525">
     6     <Window.Resources>
     7         <local:Student x:Key="student"/>
     8     </Window.Resources>
     9     <Grid>
    10         <TextBlock Height="23" HorizontalAlignment="Left" Margin="97,54,0,0" Name="textBlock1" Text="姓名" VerticalAlignment="Top" />
    11         <TextBox DataContext="{StaticResource ResourceKey=student}" Height="23" HorizontalAlignment="Left" Margin="153,54,0,0" Name="textBox1" VerticalAlignment="Top" Width="120">
    12             <TextBox.Text>
    13                 <Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
    14                     <!-- 自定义的验证规格,当然可以是多个Check -->
    15                     <Binding.ValidationRules>
    16                         <local:NameCheck />
    17                     </Binding.ValidationRules>
    18                 </Binding>
    19             </TextBox.Text>
    20             <TextBox.ToolTip>
    21                 <!--将当前的错误信息显示在tooltip上-->
    22                 <Binding RelativeSource="{RelativeSource Self}"  Path="(Validation.Errors)[0].ErrorContent"/>
    23             </TextBox.ToolTip>
    24         </TextBox>
    25     </Grid>
    26 </Window>
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Windows;
     6 using System.Windows.Controls;
     7 using System.Windows.Data;
     8 using System.Windows.Documents;
     9 using System.Windows.Input;
    10 using System.Windows.Media;
    11 using System.Windows.Media.Imaging;
    12 using System.Windows.Navigation;
    13 using System.Windows.Shapes;
    14 
    15 namespace WpfApplication4
    16 {
    17     /// <summary>
    18     /// MainWindow.xaml 的交互逻辑
    19     /// </summary>
    20     public partial class MainWindow : Window
    21     {
    22         public MainWindow()
    23         {
    24             InitializeComponent();
    25         }
    26     }
    27 
    28     public class NameCheck : ValidationRule
    29     {
    30         public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    31         {
    32             var name = Convert.ToString(value);
    33 
    34             //如果名字长度大于4则是非法
    35             if (name.Length > 4)
    36                 return new ValidationResult(false, "名字长度不能大于4个长度!");
    37 
    38             return ValidationResult.ValidResult;
    39         }
    40     }
    41 
    42     public class Student
    43     {
    44         public string Name { get; set; }
    45 
    46         public int Age { get; set; }
    47     }
    48 }

    同样这里也需要注意的就是:

    ①   实现ValidationRule接口,重写Validate方法,其中的逻辑,你懂的。

    1 public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)

    ② 然后我们在需要验证的控件上追加Rule验证, 其中的UpdateSourceTrigger设定为字段改变时触发,当然可选值有很多...

    1   <TextBox.Text>
    2                 <Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
    3                     <!-- 自定义的验证规格,当然可以是多个Check -->
    4                     <Binding.ValidationRules>
    5                         <local:NameCheck />
    6                     </Binding.ValidationRules>
    7                 </Binding>
    8             </TextBox.Text>

    ③ 最后要将实体写入到验证控件的DataContext上,最后大功告成。

    1   <TextBox DataContext="{StaticResource ResourceKey=student}" Height="23" HorizontalAlignment="Left" Margin="153,54,0,0" Name="textBox1" VerticalAlignment="Top" Width="120">
  • 相关阅读:
    jQuery插件编写步骤详解
    原生JavaScript实现JSON合并(递归深度合并)
    js原型链继承及调用父类方法
    codefind.pl
    如何为属性是disabled的表单绑定js事件
    平假名、片假名转换
    #和##在宏替换中的作用
    Perl实用中文处理步骤(修改版)
    Perl Unicode全攻略
    nio DirectByteBuffer如何回收堆外内存
  • 原文地址:https://www.cnblogs.com/huangxincheng/p/2571476.html
Copyright © 2011-2022 走看看