广告位联系
返回顶部
分享到

MVVMLight项目的绑定及各种使用场景示例介绍

Android 来源:互联网 作者:秩名 发布时间:2022-02-01 00:40:21 人浏览
摘要

一、绑定: 主要包含元素绑定和非元素绑定两种。 1、元素绑定: 是绑定的最简单形式,源对象是WPF的元素,并且源对象的属性是依赖项属性。 根据我们之前的知识 ,依赖项属性具有

一、绑定:

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

1、元素绑定:

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

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

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

如下:

1

2

3

4

<StackPanel Orientation="Vertical" HorizontalAlignment="Left" >

       <TextBox x:Name="WelcomeText" Width="200" 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下的全局资源

1

2

3

<Window.Resources>

    <SolidColorBrush x:Key="BorderBrush">Red</SolidColorBrush>

</Window.Resources>

应用到视图中

1

2

3

4

<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 属性:

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

      <StackPanel Orientation="Horizontal" >

          <TextBlock Width="150" Text="获取自身宽度:"  ></TextBlock>

          <TextBlock Width="200" Text="{Binding Path=Width,RelativeSource={RelativeSource Mode=Self}}" ></TextBlock>

      </StackPanel>

      <StackPanel Orientation="Horizontal" ToolTip="parent" >

          <TextBlock Width="150" Text="查找上一层ToolTip:" ></TextBlock> 

          <TextBlock Text="{Binding Path=ToolTip,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel}}}"></TextBlock>

      </StackPanel>

      <StackPanel Orientation="Horizontal">

          <TextBlock Width="150" Text="查找上二层ToolTip:" ></TextBlock>

          <TextBlock Text="{Binding Path=ToolTip,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type StackPanel},AncestorLevel=2}}"></TextBlock>

      </StackPanel>                              

</StackPan>

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

  Mode成员名称 说明
  FindAncestor

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

  PreviousData

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

  Self

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

  TemplatedParent

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

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

结果:

2.3 DataContext 属性:

如果想将一个对象绑定到一个由多个元素组成的视图块或者复合元素中,用DataContext 会更好开发和维护。如下

1

2

3

4

5

6

7

8

9

10

<StackPanel Orientation="Vertical" DataContext="UInfo" >

    <StackPanel Orientation="Horizontal" >

        <TextBlock Text="名称:" Width="100" ></TextBlock>

        <TextBox Text="{Binding Name}" Width="100" ></TextBox>

    </StackPanel>

    <StackPanel Orientation="Horizontal">

        <TextBlock Text="性别:" Width="100" ></TextBlock>

        <TextBox Text="{Binding Sex}" Width="100" ></TextBox>

    </StackPanel>

</StackPanel>

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

数据绑定有普通的控件绑定应用:比如 下拉框、单选框、复选框、普通文本框 、日期框等;

复杂的绑定有数据列表绑定,用户控件信息绑定等,比如 ListBox,DataGrid,UserControl绑定等。

1、下拉框:

View代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<StackPanel Margin="10,20,0,50">

  <TextBlock Text="下拉框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>

  <DockPanel x:Name="Combbox" >               

      <StackPanel DockPanel.Dock="Left" Width="240">

          <ComboBox Width="200" HorizontalAlignment="Left" ItemsSource="{Binding CombboxList}" SelectedItem="{Binding CombboxItem}" DisplayMemberPath="Text" SelectedValuePath="Key" ></ComboBox>

      </StackPanel>

       

      <StackPanel DockPanel.Dock="Right" Width="240" 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代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#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); }

 }

 #endregio

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

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

结果:

2、单选框

1

2

3

4

5

6

7

8

9

10

11

12

<StackPanel Margin="10,0,0,50">

     <TextBlock Text="单选框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>

     <DockPanel x:Name="RadioButton" >

         <StackPanel DockPanel.Dock="Left" Width="240">

             <RadioButton Content="{Binding SingleRadio}" IsChecked="{Binding IsSingleRadioCheck}" HorizontalAlignment="Right" Width="240" >

             </RadioButton>

         </StackPanel>

         <StackPanel DockPanel.Dock="Right" Width="240" Orientation="Horizontal">

             <TextBlock Text="{Binding IsSingleRadioCheck,StringFormat='结果:\{0\}'}" ></TextBlock>

         </StackPanel>

     </DockPanel>

 </StackPanel>

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

结果:

3、组合单选框

我们一般会用单选框做组合表示唯一选项,比如性别包含男女,但是只能选择一个。而更多的场景是包含多个选项,但是只能单选的,这时候就需要做单选框组。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<StackPanel Margin="10,0,0,50">

     <TextBlock Text="组合单选框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5"></TextBlock>

     <DockPanel x:Name="GroupRadioButton" >

         <StackPanel DockPanel.Dock="Left" Width="240">

             <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="240" Orientation="Horizontal">

             <TextBlock Text="{Binding RadioButton.Content,StringFormat='结果:\{0\}'}" ></TextBlock>

         </StackPanel>

     </DockPanel>

</StackPanel

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

这边有是三个属性进行绑定相关:

RadioButtons:单选框列表数据(循环绑定);Content:单选框显示的内容;IsCheck:单选框的是否选中。 

结果:

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<StackPanel Margin="10,0,0,50">

            <TextBlock Text="复合框" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>

            <DockPanel x:Name="GroupCheckButton" >

                <StackPanel DockPanel.Dock="Left" Width="240">

                    <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="240" Orientation="Horizontal">

                    <TextBlock Text="{Binding CheckInfo,StringFormat='结果:\{0\}'}" ></TextBlock>

                </StackPanel>

            </DockPanel>

</StackPanel>

结果:

5、树形控件

View代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<StackPanel Margin="10,0,0,50">

            <TextBlock Text="树" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>

            <DockPanel x:Name="TreeButton" >

                <StackPanel DockPanel.Dock="Left" Width="240">

                        <TreeView ItemsSource="{Binding TreeInfo}" x:Name="tree" BorderThickness="0">

                        <TreeView.ItemTemplate>

                            <HierarchicalDataTemplate ItemsSource="{Binding Children}">

                                <TextBlock Text="{Binding NodeName}"/>

                            </HierarchicalDataTemplate>

                        </TreeView.ItemTemplate>

                    </TreeView>

                </StackPanel>

                 

                <StackPanel DockPanel.Dock="Right" Width="240" 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代码

1

2

3

4

5

6

public class TreeNodeModel : ObservableObject

   {

       public string NodeID { get; set; }

       public string NodeName { get; set; }

       public List<TreeNodeModel> Children { get; set; }

   }

ViewModel代码

1

2

3

4

5

6

7

8

9

10

11

#region 树控件

       private List<TreeNodeModel> treeInfo;

       /// <summary>

       /// 树控件数据信息

       /// </summary>

       public List<TreeNodeModel> TreeInfo

       {

           get { return treeInfo; }

           set { treeInfo = value; RaisePropertyChanged(()=>TreeInfo); }

       }

 #endregion

 结果:

6、ListBox

当我们需要用到循环的列表内容,并且模板化程度高的时候,建议使用ListBox来做绑定。

View代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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

  <TextBlock Text="ListBox模板" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>

      <DockPanel >

          <StackPanel HorizontalAlignment="Left" DockPanel.Dock="Left" >

              <ListBox x:Name="lb" ItemsSource="{Binding ListBoxData}" Width="500" BorderThickness="0" >

                  <ListBox.ItemsPanel>

                      <ItemsPanelTemplate>

                          <WrapPanel Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"/>

                      </ItemsPanelTemplate>

                  </ListBox.ItemsPanel>

                  <ListBox.ItemTemplate>

                      <DataTemplate>

                          <StackPanel>

                              <Image Source="{Binding Img}" Width="96" Height="96"/>

                              <TextBlock HorizontalAlignment="Center" Text="{Binding Info}"/>

                          </StackPanel>

                      </DataTemplate>

                  </ListBox.ItemTemplate>

              </ListBox>

          </StackPanel>

          <StackPanel DockPanel.Dock="Right" DataContext="{Binding SelectedItem,ElementName=lb}" Margin="15" Orientation="Vertical" >

              <TextBlock Text="{Binding Info,StringFormat='选中:\{0\}'}" ></TextBlock>

          </StackPanel>

      </DockPanel>

</StackPanel>

ViewModel代码:

1

2

3

4

5

6

7

8

9

10

11

#region ListBox 模板

 private IEnumerable listBoxData;

 /// <summary>

 /// LisBox数据模板

 /// </summary>

 public IEnumerable ListBoxData

 {

     get { return listBoxData; }

     set { listBoxData = value;RaisePropertyChanged(()=>ListBoxData); }

 }

 #endregion

初始数据:

1

2

3

4

5

6

7

8

9

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中的局部视图。 这时候,使用用户控件会好很多。

我们先写一个用户控件,分别设置了他的样式和绑定的属性值,如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<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="300" d:DesignWidth="300">

     <Grid>

         <Grid.Resources>

             <Style TargetType="{x:Type StackPanel}">

                 <Style.Triggers>

                     <Trigger Property="IsMouseOver" Value="True">

                         <Setter Property="RenderTransform">

                             <Setter.Value>

                                 <RotateTransform Angle="10"></RotateTransform>

                             </Setter.Value>

                         </Setter>

                         <Setter Property="Background" Value="#3B9CFB" />

                     </Trigger>

                 </Style.Triggers>

             </Style>

         </Grid.Resources>

          

          

         <StackPanel Orientation="Vertical" Margin="10">

             <Image Source="{Binding Img}" Width="96" Height="96" />

             <TextBlock HorizontalAlignment="Center" Text="{Binding Info}"/>

         </StackPanel>

          

     </Grid>

</UserControl>

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

1

xmlns:Content="clr-namespace:MVVMLightDemo.Content"

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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

                    <TextBlock Text="用户控件模板列表" FontWeight="Bold" FontSize="12" Margin="0,5,0,5" ></TextBlock>

                    <StackPanel HorizontalAlignment="Left" Width="500" >

                         <ItemsControl ItemsSource="{Binding FiList}" HorizontalAlignment="Left" >

                            <ItemsControl.ItemTemplate>

                                <DataTemplate>

                                    <Content:FruitInfoView />

                                </DataTemplate>                      

                            </ItemsControl.ItemTemplate>

                            <!-- 面板显示模板 -->

                            <ItemsControl.ItemsPanel>

                                <ItemsPanelTemplate>

                                    <WrapPanel Orientation="Horizontal">

                                    </WrapPanel>

                                </ItemsPanelTemplate>

                            </ItemsControl.ItemsPanel>

                        </ItemsControl>

                    </StackPanel>

</StackPanel>

  结果:

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

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


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://www.cnblogs.com/wzh2010/p/6425060.html
    Tag :
相关文章
  • Kotlin的Collection与Sequence操作异同点介绍

    Kotlin的Collection与Sequence操作异同点介绍
    在Android开发中,集合是我们必备的容器,Kotlin的标准库中提供了很多处理集合的方法,而且还提供了两种基于容器的工作方式:Collection 和
  • 实现一个Kotlin函数类型方法

    实现一个Kotlin函数类型方法
    接口与函数类型 业务开发中,经常会有实现一个函数式接口(即接口只有一个方法需要实现)的场景,大家应该都会不假思索的写出如下代
  • Android10 App启动Activity源码分析
    ActivityThread的main方法 让我们把目光聚焦到ActivityThread的main方法上。 ActivityThread的源码路径为/frameworks/base/core/java/android/app/ActivityThread。 1 2
  • Android10客户端事务管理ClientLifecycleManager源码解析

    Android10客户端事务管理ClientLifecycleManager源码解析
    在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程。这
  • Kotlin对象的懒加载方式by lazy与lateinit异同介绍

    Kotlin对象的懒加载方式by lazy与lateinit异同介绍
    属性或对象的延时加载是我们相当常用的,一般我们都是使用 lateinit 和 by lazy 来实现。 他们两者都是延时初始化,那么在使用时那么他们两
  • Android类加载流程分析

    Android类加载流程分析
    本文分析的代码基于Android8.1.0源码。 流程分析 从loadClass开始,我们来看下Android中类加载的流程 /libcore/ojluni/src/main/java/java/lang/ClassLoader.ja
  • Android实现读写USB串口数据的代码

    Android实现读写USB串口数据的代码
    最近在研究USB方面的内容;先后做了关于Android读写HID、串口设备的DEMO。本文比较简单,主要介绍的是Android实现读取串口数据的功能 废话不
  • Epoxy - 在RecyclerView中构建复杂界面
    Diffing 对于复杂数据结构支持的多个视图类型展示在屏幕上, Epoxy此时是尤其有用的. 在这些场景中, 数据可能会被网络请求, 异步 Observable, 用
  • Android性能优化的详细介绍

    Android性能优化的详细介绍
    性能优化是一个app很重要的一部分,一个性能优良的app从被下载到启动到使用都能给用户到来很好的体验。自然我们做性能优化也是从被下
  • Android进阶宝典-插件化2(Hook启动插件中四大组件

    Android进阶宝典-插件化2(Hook启动插件中四大组件
    在上一节,我们主要介绍了如果通过反射来加载插件中的类,调用类中的方法;既然插件是一个apk,其实最重要的是启动插件中的Activity、
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计