一、绑定:

主要包含元素绑定和非元素绑定两种。

1、元素绑定,是绑定的最简单形式,源对象是WPF的元素,并且源对象的属性是依赖项属性。

根据我们之前的知识 ,依赖项属性具有内置的更改通知支持。所以当我们的源对象中改变依赖项属性的值时,会立即更新目标对象中的绑定属性。

以上篇的例子来重写,我们不用额外定义全局公开的属性来支持数据的显示。

如下:

  <StackPanel Orientation="Vertical" HorizontalAlignment="Left" >
<TextBox x:Name="WelcomeText" Width="" Margin="10,10,0,0"></TextBox>
<TextBlock Text="{Binding ElementName=WelcomeText,Path=Text,StringFormat='Hello \{0\}'}" Margin="10,10,0,0"></TextBlock>
</StackPanel>

TextBlock 绑定了名称为WelcomeText的元素,并且将Path指向Text属性,所以他的值会跟着 WelcomeText的变化而变化。

2、非元素类型绑定: 

2.1 Source属性:绑定具体的数据对象:如系统信息跟我们定义的资源数据。

定义Window下的全局资源

     <Window.Resources>
<SolidColorBrush x:Key="BorderBrush">Red</SolidColorBrush>
</Window.Resources>

应用到视图中

   <StackPanel Margin="10,50,0,0" Orientation="Vertical" >
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}" ></TextBlock>
<TextBlock Text="{Binding Source={StaticResource BorderBrush}}" Foreground="{Binding Source={StaticResource BorderBrush}}" ></TextBlock>
</StackPanel>

结果:

 2.2 RelativeSource 属性:设置该属性 可以根据当前目标对象的相对关系指向源目标。比如获取当前对象的父亲对象、兄弟对象或者自身的其他属性等一些数据。

            <StackPanel Margin="10,50,0,0" Orientation="Vertical" ToolTip="top" >

                 <StackPanel Orientation="Horizontal" >
<TextBlock Width="" Text="获取自身宽度:" ></TextBlock>
<TextBlock Width="" Text="{Binding Path=Width,RelativeSource={RelativeSource Mode=Self}}" ></TextBlock>
</StackPanel> <StackPanel Orientation="Horizontal" ToolTip="parent" >
<TextBlock Width="" Text="查找上一层ToolTip:" ></TextBlock>
<TextBlock Text="{Binding Path=ToolTip,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}}}"></TextBlock>
</StackPanel> <StackPanel Orientation="Horizontal">
<TextBlock Width="" Text="查找上二层ToolTip:" ></TextBlock>
<TextBlock Text="{Binding Path=ToolTip,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel},AncestorLevel=2}}"></TextBlock>
</StackPanel> </StackPanel>

代码很容易理解,这边在创建RelativeSource的时候,mode模式有四种类型:

 
  Mode成员名称 说明
  FindAncestor

引用数据绑定元素的父链中的上级。 这可用于绑定到特定类型的上级或其子类。 若要指定 AncestorType 和/或 AncestorLevel,这就是应使用的模式。

  PreviousData

允许在当前显示的数据项列表中绑定上一个数据项(不是包含数据项的控件)。

  Self

引用正在其上设置绑定的元素,并允许你将该元素的一个属性绑定到同一元素的其他属性上。

  TemplatedParent

引用应用了模板的元素,其中此模板中存在数据绑定元素。 这类似于设置 TemplateBindingExtension,且仅在 Binding 位于模板内部时适用。

注意:AncestorType 指得是查找的对象类型,AncestorLevel 代表搜索的层级的位置,如果是3,则忽略前两个发现的元素。

结果:
2.3 DataContext 属性:如果想将一个对象绑定到一个由多个元素组成的视图块或者复合元素中,用DataContext 会更好开发和维护。如下
             <StackPanel Orientation="Vertical" DataContext="UInfo" >

                 <StackPanel Orientation="Horizontal" >
<TextBlock Text="名称:" Width="" ></TextBlock>
<TextBox Text="{Binding Name}" Width="100" ></TextBox>
</StackPanel> <StackPanel Orientation="Horizontal">
<TextBlock Text="性别:" Width="" ></TextBlock>
<TextBox Text="{Binding Sex}" Width="100" ></TextBox>
</StackPanel> </StackPanel>

二、绑定的各种使用场景:

数据绑定有普通的控件绑定应用:比如 下拉框、单选框、复选框、普通文本框 、日期框等;
复杂的绑定有数据列表绑定,用户控件信息绑定等,比如 ListBox,DataGrid,UserControl绑定等。

1、下拉框:

View代码:

                 <StackPanel Margin="10,20,0,50">
<TextBlock Text="下拉框" FontWeight="Bold" FontSize="" Margin="0,5,0,5" ></TextBlock>
<DockPanel x:Name="Combbox" >
<StackPanel DockPanel.Dock="Left" Width="">
<ComboBox Width="" HorizontalAlignment="Left" ItemsSource="{Binding CombboxList}" SelectedItem="{Binding CombboxItem}" DisplayMemberPath="Text" SelectedValuePath="Key" ></ComboBox>
</StackPanel> <StackPanel DockPanel.Dock="Right" Width="" Orientation="Horizontal" DataContext="{Binding CombboxItem}" >
<TextBlock Text="{Binding Key,StringFormat='结果:\{0\}'}" Margin="0,0,15,0" ></TextBlock>
<TextBlock Text="{Binding Text}"></TextBlock>
</StackPanel> </DockPanel>
</StackPanel>

Model代码:

   public class ComplexInfoModel:ObservableObject
{
private String key;
/// <summary>
/// Key值
/// </summary>
public String Key
{
get { return key; }
set { key = value; RaisePropertyChanged(()=>Key); }
} private String text;
/// <summary>
/// Text值
/// </summary>
public String Text
{
get { return text; }
set { text = value; RaisePropertyChanged(()=>Text); }
}
}

ViewModel代码:

         #region 下拉框相关
private ComplexInfoModel combboxItem;
/// <summary>
/// 下拉框选中信息
/// </summary>
public ComplexInfoModel CombboxItem
{
get { return combboxItem; }
set { combboxItem = value; RaisePropertyChanged(() => CombboxItem); }
} private List<ComplexInfoModel> combboxList;
/// <summary>
/// 下拉框列表
/// </summary>
public List<ComplexInfoModel> CombboxList
{
get { return combboxList; }
set { combboxList = value; RaisePropertyChanged(()=>CombboxList); }
}
#endregion

说明:CombboxItem是一个全局的属性,作用在当前页面的数据上下文中,结果显示的内容指向下拉框中的选中值,达到共用一个数据的目的。

这边有四个地方需要注意的:ItemsSource:数据源;SelectedItem:选中的项;DisplayMemberPath:绑定时显示的所属值;SelectedValuePath :绑定时候key的所属值。 

结果:

2、单选框

             <StackPanel Margin="10,0,0,50">
<TextBlock Text="单选框" FontWeight="Bold" FontSize="" Margin="0,5,0,5" ></TextBlock>
<DockPanel x:Name="RadioButton" >
<StackPanel DockPanel.Dock="Left" Width="">
<RadioButton Content="{Binding SingleRadio}" IsChecked="{Binding IsSingleRadioCheck}" HorizontalAlignment="Right" Width="" >
</RadioButton>
</StackPanel>
<StackPanel DockPanel.Dock="Right" Width="" Orientation="Horizontal">
<TextBlock Text="{Binding IsSingleRadioCheck,StringFormat='结果:\{0\}'}" ></TextBlock>
</StackPanel>
</DockPanel>
</StackPanel>

说明:注意这边使用到了两个属性: SingleRadio,IsSingleRadioCheck,一个用于显示单选框内容,一个用于表示是否选中

结果:

3、组合单选框

我们一般会用单选框做组合表示唯一选项,比如性别包含男女,但是只能选择一个。而更多的场景是包含多个选项,但是只能单选的,这时候就需要做单选框组。
             <StackPanel Margin="10,0,0,50">
<TextBlock Text="组合单选框" FontWeight="Bold" FontSize="" Margin="0,5,0,5"></TextBlock>
<DockPanel x:Name="GroupRadioButton" >
<StackPanel DockPanel.Dock="Left" Width="">
<ItemsControl ItemsSource="{Binding RadioButtons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Content}" IsChecked="{Binding IsCheck}" GroupName="RadioButtons"
Command="{Binding DataContext.RadioCheckCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}">
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel> <StackPanel DockPanel.Dock="Right" Width="" Orientation="Horizontal">
<TextBlock Text="{Binding RadioButton.Content,StringFormat='结果:\{0\}'}" ></TextBlock>
</StackPanel>
</DockPanel>
</StackPanel>

这边使用了ItemsControl,可以根据模板来定义内容,我们在模板中放置我们需要用到的内容。这边需要注意的是:GroupName用一样的,来代表这是一个单选控件组合。

这边有是三个属性进行绑定相关:
RadioButtons:单选框列表数据(循环绑定);Content:单选框显示的内容;IsCheck:单选框的是否选中。 

结果:

4、复选框,复选框与单选框的使用情况类似:

   <StackPanel Margin="10,0,0,50">
<TextBlock Text="复合框" FontWeight="Bold" FontSize="" Margin="0,5,0,5" ></TextBlock>
<DockPanel x:Name="GroupCheckButton" >
<StackPanel DockPanel.Dock="Left" Width="">
<ItemsControl ItemsSource="{Binding CheckButtons}" x:Name="cbt" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Content}" IsChecked="{Binding IsCheck}"
Command="{Binding DataContext.CheckCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel> <StackPanel DockPanel.Dock="Right" Width="" Orientation="Horizontal">
<TextBlock Text="{Binding CheckInfo,StringFormat='结果:\{0\}'}" ></TextBlock>
</StackPanel>
</DockPanel>
</StackPanel>

结果:

5、树形控件

View代码:

   <StackPanel Margin="10,0,0,50">
<TextBlock Text="树" FontWeight="Bold" FontSize="" Margin="0,5,0,5" ></TextBlock>
<DockPanel x:Name="TreeButton" >
<StackPanel DockPanel.Dock="Left" Width="">
<TreeView ItemsSource="{Binding TreeInfo}" x:Name="tree" BorderThickness="">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding NodeName}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel> <StackPanel DockPanel.Dock="Right" Width="" Orientation="Horizontal" DataContext="{Binding SelectedItem,ElementName=tree}">
<TextBlock Text="结果:"/>
<TextBlock Text="{Binding NodeID,StringFormat='NodeID:\{0\}'}" Margin="0,0,20,0" />
<TextBlock Text="{Binding NodeName,StringFormat='NodeName:\{0\}'}"/>
</StackPanel>
</DockPanel>
</StackPanel>

Model代码

  public class TreeNodeModel : ObservableObject
{
public string NodeID { get; set; }
public string NodeName { get; set; }
public List<TreeNodeModel> Children { get; set; }
}

ViewModel代码

   #region 树控件

         private List<TreeNodeModel> treeInfo;
/// <summary>
/// 树控件数据信息
/// </summary>
public List<TreeNodeModel> TreeInfo
{
get { return treeInfo; }
set { treeInfo = value; RaisePropertyChanged(()=>TreeInfo); }
} #endregion

结果:

6、ListBox

当我们需要用到循环的列表内容,并且模板化程度高的时候,建议使用ListBox来做绑定。
View代码:
             <StackPanel Margin="10,0,0,50" Orientation="Vertical" >
<TextBlock Text="ListBox模板" FontWeight="Bold" FontSize="" Margin="0,5,0,5" ></TextBlock>
<DockPanel >
<StackPanel HorizontalAlignment="Left" DockPanel.Dock="Left" >
<ListBox x:Name="lb" ItemsSource="{Binding ListBoxData}" Width="" BorderThickness="" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel> <ListBox.ItemTemplate>
13 <DataTemplate>
14 <StackPanel>
15 <Image Source="{Binding Img}" Width="96" Height="96"/>
16 <TextBlock HorizontalAlignment="Center" Text="{Binding Info}"/>
17 </StackPanel>
18 </DataTemplate>
19 </ListBox.ItemTemplate>
</ListBox>
</StackPanel> <StackPanel DockPanel.Dock="Right" DataContext="{Binding SelectedItem,ElementName=lb}" Margin="" Orientation="Vertical" >
<TextBlock Text="{Binding Info,StringFormat='选中:\{0\}'}" ></TextBlock>
</StackPanel>
</DockPanel>
</StackPanel>

ViewModel代码:

         #region ListBox 模板

         private IEnumerable listBoxData;
/// <summary>
/// LisBox数据模板
/// </summary>
public IEnumerable ListBoxData
{
get { return listBoxData; }
set { listBoxData = value;RaisePropertyChanged(()=>ListBoxData); }
} #endregion

初始数据:

    private void InitListBoxList()
{
ListBoxData = new ObservableCollection<dynamic>(){
new { Img="/MVVMLightDemo;component/Images/1.jpg",Info="樱桃" },
new { Img="/MVVMLightDemo;component/Images/2.jpg",Info="葡萄" },
new { Img="/MVVMLightDemo;component/Images/3.jpg",Info="苹果" },
new { Img="/MVVMLightDemo;component/Images/4.jpg",Info="猕猴桃" },
new { Img="/MVVMLightDemo;component/Images/5.jpg",Info="柠檬" },
};
}

结果:

7、用户控件的集合绑定:

ListBox的列表绑定远远不能满足我们实际工作中的需求,
出于对灵活性、复用性以及代码精简的考虑,需要保证循环列表中的单个元素是独立的元素片段,类似Web中的局部视图。 这时候,使用用户控件会好很多。
 
我们先写一个用户控件,分别设置了他的样式和绑定的属性值,如下:
 <UserControl x:Class="MVVMLightDemo.Content.FruitInfoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="" d:DesignWidth="">
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type StackPanel}">
<Style.Triggers>
12 <Trigger Property="IsMouseOver" Value="True">
13 <Setter Property="RenderTransform">
14 <Setter.Value>
15 <RotateTransform Angle="10"></RotateTransform>
16 </Setter.Value>
17 </Setter>
18 <Setter Property="Background" Value="#3B9CFB" />
19 </Trigger>
20 </Style.Triggers>
21 </Style>
</Grid.Resources> <StackPanel Orientation="Vertical" Margin="">
26 <Image Source="{Binding Img}" Width="96" Height="96" />
27 <TextBlock HorizontalAlignment="Center" Text="{Binding Info}"/>
</StackPanel> </Grid>
</UserControl>

在目标视图页面注册并使用:

 xmlns:Content="clr-namespace:MVVMLightDemo.Content" 
  <StackPanel Margin="10,0,0,50" Orientation="Vertical" >
<TextBlock Text="用户控件模板列表" FontWeight="Bold" FontSize="" Margin="0,5,0,5" ></TextBlock>
<StackPanel HorizontalAlignment="Left" Width="" >
<ItemsControl ItemsSource="{Binding FiList}" HorizontalAlignment="Left" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Content:FruitInfoView />
</DataTemplate>
</ItemsControl.ItemTemplate> <!-- 面板显示模板 -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal">
15 </WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel> </ItemsControl> </StackPanel>
</StackPanel>

结果:

后记:这篇更确切的说是绑定的相关知识,只是应用了MVVM模式来实现。

工作太忙了,写的太慢,其实后面几篇都已经成稿了,一直放在Note里面等待认真检查,品质太差怕误导其他开发人员。

点击下载代码

转载请标明出处,谢谢

利刃 MVVMLight 4:绑定和绑定的各种使用场景的更多相关文章

  1. 利刃 MVVMLight 10:Messenger 深入

    1.Messager交互结构和消息类型 衔接上篇,Messeger是信使的意思,顾名思义,他的目是用于View和ViewModel 以及 ViewModel和ViewModel 之间的消息通知和接收. ...

  2. 利刃 MVVMLight

    已经很久没有写系列文章了,上一次是2012年写的HTLM5系列,想想我们应该是较早一批使用HTML5做项目的人. 相比我当时动不动100+的粉丝增长和两天3000+的阅读量,MVVM Light只能算 ...

  3. 背水一战 Windows 10 (19) - 绑定: TemplateBinding 绑定, 与 RelativeSource 绑定, 与 StaticResource 绑定

    [源码下载] 背水一战 Windows 10 (19) - 绑定: TemplateBinding 绑定, 与 RelativeSource 绑定, 与 StaticResource 绑定 作者:we ...

  4. WINDOWS下绑定ARP绑定网关

    一.WINDOWS下绑定ARP绑定网关步骤一:在能正常上网时,进入MS-DOS窗口,输入命令:arp -a,查看网关的IP对应的正确MAC地址, 并将其记录下来.注意:如果已经不能上网,则先运行一次命 ...

  5. 绑定: TemplateBinding 绑定, 与 RelativeSource 绑定, 与 StaticResource 绑定

    介绍背水一战 Windows 10 之 绑定 TemplateBinding 绑定 与 RelativeSource 绑定 与 StaticResource 绑定 示例1.演示 TemplateBin ...

  6. 重新想象 Windows 8 Store Apps (52) - 绑定: 与 Element Model Indexer Style RelativeSource 绑定, 以及绑定中的数据转换

    [源码下载] 重新想象 Windows 8 Store Apps (52) - 绑定: 与 Element Model Indexer Style RelativeSource 绑定, 以及绑定中的数 ...

  7. Linux驱动手动绑定和解绑定

    Linux内核从2.6.13-rc3开始,提供了在用户空间,可动态的绑定和解绑定设备和设备驱动之间关系的功能.在这之前,只能通过insmod(modprobe)和rmmod来绑定和解绑,而且这种绑定和 ...

  8. Angular4.x 创建组件|绑定数据|绑定属性|数据循环|条件判断|事件|表单处理|双向数据绑定

    Angular4.x 创建组件|绑定数据|绑定属性|数据循环|条件判断|事件|表单处理|双向数据绑定 创建 angular 组件 https://github.com/angular/angular- ...

  9. Linux驱动手动绑定和解绑定方法

    linux内核从2.6.13-rc3开始,提供了在用户空间,可动态的绑定和解绑定设备和设备驱动之间关系的功能.在这之前,只能通过insmod(modprobe)和rmmod来绑定和解绑,而且这种绑定和 ...

  10. JDBC_05_ResorceBundle(资源绑定器) 绑定配置文件

    ResorceBundle(资源绑定器) 绑定配置文件 jdbc.proprtise 需要在src目录下新建一个文件夹然后将jdbc.proprtise放在文件中然后右键该文件夹选择 Rebuild ...

随机推荐

  1. PHP 合并数组 追加数组例子

    PHP合并数组我们可以使用array_merge()函数,array_merge()函数返回一个联合的数组.所得到的数组以第一个输入数组参数开始,按后面数组参数出现的顺序依次追加.其形式为: arra ...

  2. 在asp.net中使用ajax记录

    一.问题描述 ajax在mvc中使用频繁,比如cms中的评论功能,但由于涉及到前后端开发,日久容易忘,在此做下记录. 二.内容 控制器中代码示例: /// <summary> /// 在文 ...

  3. html中object标签详解

        定义和用法 object标签定义一个嵌入的对象.请使用此元素向您的 XHTML 页面添加多媒体.此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码. &l ...

  4. Beanstalkd使用

    Beanstalkd,一个高性能.轻量级的分布式内存队列系统,最初设计的目的是想通过后台异步执行耗时的任务来降低高容量Web应用系统的页面访问延迟,支持过有9.5 million用户的Facebook ...

  5. 使用AIR进行移动APP开发常见功能和问题(下)

    1.  Air如何判断android.ios 平台网络连接状态? Android,使用as3原生api: if(NetworkInfo.isSupported)//只有android支持 Networ ...

  6. MySQL数据类型--日期时间

    一.博客前言 自接触学习MySQL已有一段时间了,对于MySQL的基础知识还是略懂略懂的.在这一路学习过来,每次不管看书还是网上看的资料,对于MySQL数据类型中的时间日期类型总是一扫而过,不曾停下来 ...

  7. PrefixSpan算法原理总结

    前面我们讲到频繁项集挖掘的关联算法Apriori和FP Tree.这两个算法都是挖掘频繁项集的.而今天我们要介绍的PrefixSpan算法也是关联算法,但是它是挖掘频繁序列模式的,因此要解决的问题目标 ...

  8. MIPS 跳转指令BAL vs JAL

    今天调试程序,发现在windows和Linux下,diab编译的结果不一样,一个能跑一个不能跑.最后定位到了函数跳转上. 程序代码里的函数跳转写的是BAL,在windows下编译结果正常,在Linux ...

  9. IOS控件布局之Masonry布局框架

    前言: 回想起2013年做iOS开发的时候,那时候并没有采用手写布局代码的方式,而是采用xib文件来编写,如果使用纯代码方式是基于window的size(320,480)计算出一个相对位置进行布局,那 ...

  10. [转载] 几张非常有意义的JavaScript基础学习思维图

    原文:http://www.w3cfuns.com/forum.php?mod=viewthread&tid=5598364&extra=page%3D1%26filter%3Ddig ...