8天入门wpf—— 第五天 数据绑定

     

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

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

     

一: 控件到控件的绑定

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

8天入门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>

8天入门wpf—— 第五天 数据绑定

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

 

二:.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>

8天入门wpf—— 第五天 数据绑定

 

首先谢天谢地,我们的数据出来了,好,现在我们有需求了,我现在需要给奇偶行填充不同底色,并且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 }

8天入门wpf—— 第五天 数据绑定

快看,效果出来了,这里要稍微解释下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 }

8天入门wpf—— 第五天 数据绑定

 

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

①   实现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">

你可能感兴趣的:(数据绑定)