在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">