您的位置:首页 > 业界新闻

学习WPF,转向移动互联网(windows phone && windows 8 )开发(下)

2012-07-25 14:20 615 查看
一、
绑定(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 绑定到另一个元素的某个属性值。Eg:TextBoxA的Text目标数属性绑定 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实现Convert和ConvertBack方法。




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属性,Mode为OneWay。
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 }

数据验证ValidationRule(System.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属性,RowNum为int型,当在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
里的内容与边框的之间的间隔。

转自:/content/4313476.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐