WPF MVVM基础教程(五)RelativeSource属性绑定

news2024/9/20 16:28:29

RelativeSource属性绑定

  • 介绍
  • RelativeSource属性介绍
    • RelativeSource的Mode属性有四种模式:
  • 四种模式用法
    • Self模式
    • FindAncestor模式
      • 使用规则:
    • TemplatedParent模式
    • PreviousData模式
  • 特殊用法
      • 绑定到其他ViewModel上的命令

介绍

RelativeSource 是一个标记扩展,扩展描述相对于绑定目标位置的绑定源位置。

RelativeSource 作用是改变绑定指向的源,默认使用绑定的源是对应的DataContext对象中的属性,如果想要绑定源为其他元素,比如自身、其他父级控件、其他ViewModel,就需要用RelativeSource 进行标记。它表示在绑定表达式中引用另一个元素的属性。它使开发人员可以根据元素的位置和类型来查找绑定源。

RelativeSource属性介绍

属性解释
AncestorLevel以 FindAncestor 模式获取或设置要查找的上级级别。 使用 1 指示最靠近绑定目标元素的项。
AncestorType指定查找的上级节点的类型。
Mode获取或设置 RelativeSourceMode 值,该值描述相对于绑定目标的位置的绑定源的位置。Mode属性是一个RelativeSourceMode 枚举
PreviousData一个静态值,效果等同于 Mode=PreviousData。该值用于返回为 RelativeSource 模式构造的 PreviousData。
Self一个静态值,效果等同于 Mode=Self。该值用于返回为 RelativeSource 模式构造的 Self。
TemplatedParent一个静态值,效果等同于 Mode=TemplatedParent。该值用于返回为 RelativeSource 模式构造的 TemplatedParent。

RelativeSource的Mode属性有四种模式:

RelativeSource属性有四种模式:

  1. FindAncestor:查找指定类型的父元素,和 AncestorType 或 AncestorLevel 一起使用。
  2. PreviousData:使用数据提供程序中的前一个数据项。
  3. Self:使用当前元素。
  4. TemplatedParent:查找元素的模板父级。

四种模式用法

Self模式

绑定控件本身的属性

示例:

实现正方形控件(宽和高相等),通过RelativeSource 实现,使用Self将Width绑定到Height上。

Width="{Binding RelativeSource={RelativeSource Self}, Path=Height}"

//或者
Width="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Height}"

控件的Xaml代码:

 <Button
            Width="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Height}"
            Height="100"
            Margin="40,67,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Content="Button"/>

效果:

只需要修改Height值,Width就会跟着变化

在这里插入图片描述

FindAncestor模式

绑定控件父元素及更上一级的元素,使用Mode=FindAncestor和AncestorType 、 AncestorLevel配合实现。

使用规则:

  1. 必须要设置AncestorType 属性,只要设置了Mode=FindAncestorAncestorLevel值,就必须要设置AncestorType 属性,否则会报错。
  2. 如果未显式设置属性 Mode,则设置AncestorTypeAncestorLevel属性会将属性值隐式锁定 Mode 为 FindAncestor。(Mode=FindAncestor可省略)
  3. AncestorLevel设置为1就是默认找到的第一个指定类型的父元素,2就是第二个
  4. 绑定成功的还有一点,对应父元素相关属性必须有值,如果对应父元素对应属性无值,则无效果。

如下几种定义效果是相同的

RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType=Grid}
RelativeSource={RelativeSource AncestorLevel=1, AncestorType=Grid}
RelativeSource={RelativeSource AncestorType=Grid}

示例:

通过设置一个Button的Width和不同父级布局控件的宽度绑定来演示FindAncestor模式
在这里插入图片描述

当前界面代码:

<Window
    x:Class="WpfRelativeSourceExample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfRelativeSourceExample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <StackPanel Background="LightGray">
            <Grid
                Width="768"
                Height="380"
                Margin="0,27,0,0"
                HorizontalAlignment="Left"
                Background="Gray">
                <Grid
                    Width="396"
                    Height="344"
                    Margin="0,36,0,0"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    Background="Linen">
                    <Canvas Margin="0,53,173,0" Background="DarkCyan" >
                        <Button
                            Canvas.Top="56"
                            Height="100"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Top"
                            Content="Button" />
                    </Canvas>
                </Grid>
            </Grid>
        </StackPanel>
    </Grid>
</Window>

将Button的Width设置和Canvas一样,增加下面的绑定

Width="{Binding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Canvas}}"

此时并未生效

在这里插入图片描述

因为规则4中说明对应Canvas未定义,对应的Width属性,所有无法生效,只要对应Canvas设置了Width属性,RelativeSource就生效了。

增加Width

然后依次跟上面两级的Grid的绑定

第一级:

  <Button
          Canvas.Top="56"
          Width="{Binding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
          Height="100"
          HorizontalAlignment="Center"
          VerticalAlignment="Top"
          Content="Button" />
                            
//等效                    
<Button
	       Canvas.Top="56"
	       Width="{Binding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType=Grid}}"
	       Height="100"
	       HorizontalAlignment="Center"
	       VerticalAlignment="Top"
	       Content="Button" />

在这里插入图片描述

第二级:

<Button
        Canvas.Top="56"
          Width="{Binding Width, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=2, AncestorType=Grid}}"
          Height="100"
          HorizontalAlignment="Center"
          VerticalAlignment="Top"
          Content="Button" />

在这里插入图片描述

TemplatedParent模式

TemplatedParent模式主要用在重写或者定义控件模板Template中,用于将模板中的属性和控件本身的属性绑定,类似TemplateBinding,可以对TemplateBinding进行扩展,利用Converter实现一些TemplateBinding不支持的属性绑定

示例:

 <Button
            Margin="49,60,0,0"
            Padding="10"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            Content="Button">
            <Button.Style>
                <Style TargetType="Button">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <Border Background="{TemplateBinding Background}">
                                    <ContentPresenter Margin="{Binding Path=Padding, RelativeSource={RelativeSource TemplatedParent}}" Content="{TemplateBinding Content}" />
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Button.Style>
        </Button>

PreviousData模式

PreviousData可以在数据绑定表达式中使用前一个数据项。通常在ItemsControl中使用,用于根据前一个项的属性计算当前项的属性。PreviousData只能在ItemsControl或其派生类中使用。

使用场景,暂无示例

特殊用法

使用RelativeSource改变绑定的ViewModel对象。在嵌套的ViewModel中,命令一定要写在对应的VIewModel(或者Model)中才能实现绑定,这时可以通过RelativeSource绑定到其父级的ViewModel中的命令上。

比如在DataGrid列中有按钮事件,就必须对应的命令需要写在对应的Model中增加命令

正常下一个DataGird(在用户控件UserManageUC.xaml中)

<DataGrid
            Width="605"
            Height="341"
            Margin="59,74,0,0"
            HorizontalAlignment="Left"
            VerticalAlignment="Top"
            AutoGenerateColumns="False"
            ItemsSource="{Binding Users}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Id}" Header="序号" />
                <DataGridTextColumn Binding="{Binding Name}" Header="姓名" />
                <DataGridTextColumn Binding="{Binding Age}" Header="年龄" />
                <DataGridTemplateColumn Header="操作">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Button Command="{Binding ModifyCmd}" Content="修改" />
                                <Button Content="删除" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

对应的数据模型UserModel

 public class UserModel
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public CommandBase ModifyCmd
        {
            get
            {
                return new CommandBase(o =>
                {
                    MessageBox.Show($"UserModel Modify:{Name}");
                });
            }
        }

    }
}

在对应的ViewModel创建集合并初始化

public class UserManageUCViewModel : ViewModelBase
    {
        public ObservableCollection<UserModel> Users{ get; set; }


        public UserManageUCViewModel()
        {
            Users= new ObservableCollection<UserModel>();
            Users.Add(new UserModel() { Id=1,Name="张三",Age=11});
            Users.Add(new UserModel() { Id=2,Name="李四",Age=22});
        }

    }

此时效果,正常使用命令

在这里插入图片描述

绑定到其他ViewModel上的命令

在UserManageUCViewModel 上添加命令

public CommandBase ModifyCmd
{
    get
    {
        return new CommandBase(o =>
        {
            var user=o as UserModel;
            MessageBox.Show($"UserManageUCViewModel Modify:{user.Name}");
        });
    }
}

改变按钮Command的绑定,使用RelativeSource的FindAncestor模式RelativeSource={RelativeSource AncestorType=local:UserManageUC}帮绑定对象改为UserManageUC用户控件,然后目标改为DataContext.ModifyCmd,然后增加CommandParameter,将该行绑定的数据作为命令参数传入

  <Button
        Command="{Binding DataContext.ModifyCmd, RelativeSource={RelativeSource AncestorType=local:UserManageUC}}"
        CommandParameter="{Binding}"
        Content="修改" />

效果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端HTML学习(二)

1、列表标签 列表标签概述&#xff1a;能够使用无序列表、有序列表、自定义列表标签&#xff0c;实现网页中列表结构的搭建。列表应用在网页中按照行展示关联性的内容&#xff0c;如:新闻列表、排行榜、账单等。 特点&#xff1a;按照行的方式&#xff0c;整齐显示内容 种类&a…

大模型遭泄两月后 Meta意外变赢家

一份被意外泄露的谷歌内部文件&#xff0c;将Meta的LLaMA大模型“非故意开源”事件再次推到聚光灯前。 “泄密文件”的作者据悉是谷歌内部的一位研究员&#xff0c;他大胆指出&#xff0c;开源力量正在填平OpenAI与谷歌等大模型巨头们数年来筑起的护城河&#xff0c;而最大的受…

Ae:摄像机命令

Ae 中提供了一些摄像机命令&#xff0c;可帮助更好地运用摄像机&#xff0c;比如实现跟焦、切换对焦对象&#xff08;图层&#xff09;、展现指定图层内容等等。 Ae菜单&#xff1a;图层/摄像机 Camera 这些命令也可在摄像机图层的右键菜单中选择。 基于 3D 视图生成摄像机 Cre…

MySQL基础-数据库介绍

本文介绍MySQL基础&#xff0c;包括什么是数据库&#xff0c;什么是关系型数据库&#xff0c;数据库和实例区别&#xff0c;数据库分类 文章目录 前言什么是数据库&#xff1f;什么是数据库管理系统&#xff08;DBMS&#xff09;&#xff1f;什么是关系型数据库管理系统&#x…

Springboot +Flowable,设置流程变量的方式(一)

一.简介 为什么需要流程变量。 举个例子&#xff0c;假设有如下一个流程&#xff0c;截图如下&#xff1a; 这是一个请假流程&#xff0c;那么谁请假、请几天、起始时间、请假理由等等&#xff0c;这些都需要说明&#xff0c;不然领导审批的依据是啥&#xff1f;那么如何传递…

HTML + CSS (包含移动Web) 笔记

前言 主要还是比较的一些html css&#xff1b;当然也有一些css样式时平时开发中经常用到的&#xff0c;但是我不晓得的&#xff0c;所以还是记录一下吧&#xff1b;给孩子点点关注吧&#xff01;&#x1f62d; 壹、HTML 一、标签 1.1 标题标签 块级元素 <h1> 好好…

go-micro框架-01-启动微服务及微服务间的调用

文章目录 1. 环境准备1.1 安装protoc1.2 安装 go-micro 2. 创建微服务项目2.1 创建第一个服务2.2 初始化2.3 同法再创建2个服务2.4 初始化项目 3. 微服务间调用4. 使用 consul4.1 启动consul4.2 修改代码 1. 环境准备 1.1 安装protoc https://github.com/protocolbuffers/pro…

webpack: 5 报错,错误

webpack-报错&#xff1a;Uncaught ReferenceError: $ is not defined (webpack) webpack打包jquery的插件&#xff08;EasyLazyLoad&#xff09;时&#xff0c;报错 方法一&#xff1a; //多个js文件用到jquery&#xff0c;用这种方法 在jquery.min.js的做最后写上下面的代码…

中交路桥科技浅谈:边坡稳定的影响因素及边坡主要监测内容

边坡稳定的影响因素 岩&#xff08;土&#xff09;性质的影响&#xff1a;包括岩石的坚硬程度、抗风化能力、抗软化能力、强度、组成、透水性等&#xff1b; 岩土结构的影响&#xff1a;表现为节理裂缝的发育程度及其分布规律、结构面的胶结情况、软弱面和破碎带的分布与边坡…

记录--ThreeJs手搓一个罗盘特效

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 先上效果 前言 最近在学Three.js.,对着文档看了一周多&#xff0c;正好赶上码上掘金的活动&#xff0c;就顺便写了一个小demo&#xff0c;手搓一个罗盘特效。 太极 先来看一下太极的实现方式&#xff…

教你一招轻松搞定大量视频滚动字幕

如果你也想批量快速的给大量视频画面添加上滚动字幕的话&#xff0c;那你一定要看这个教程&#xff0c;今天小编要给大家分享一个可以批量给大量视频添加滚动字幕的简单方法&#xff0c;有需要的小伙伴们可以一起来看看具体的操作步骤&#xff01; 首先我们来看看用这个工具添加…

c语言-指针

指针详解 ​ 这段时间在看 Linux内核&#xff0c;深觉C语言功底不扎实&#xff0c;很多代码都看不太懂&#xff0c;深入学习巩固C语言的知识很有必要。先从指针开始。 什么是指针 ​ C语言里&#xff0c;变量存放在内存中&#xff0c;而内存其实就是一组有序字节组成的数组&…

跨域时怎么处理 cookie?

前言 一个请求从发出到返回&#xff0c;需要浏览器和服务端的协调配合。浏览器要把自己的请求参数带给服务端&#xff0c;服务端校验参数之后&#xff0c;除了返回数据&#xff0c;也可能会顺便把请求是否缓存&#xff0c;cookie等信息告诉浏览器。当请求是跨域请求的时候&…

uniapp仿淘宝购物车demo

项目是基于uview2.0的ui组件&#xff0c;并且在一定程度上修改过原本组件的代码&#xff08;app-navbar是使用u-navbar在进行二次封装的组件&#xff1b;u-number-box也进行了修改&#xff09;&#xff0c;符合项目需求&#xff08;这个看个人项目需求在进行修改&#xff09; u…

【 在线音乐平台(onlinemusic) 】

文章目录 一、核心功能二、效果演示三、创建项目四、数据库设计及配置数据库4.1 数据库和表设计4.2 配置连接数据库 五、创建配置类六、具体功能实现6.1 注册模块6.2 登录模块拓展&#xff1a;登录注册加密(MD5&#xff0c;BCrypt) 6.3 退出模块6.4 上传音乐模块知识拓展1&…

RabbitMQ详解(六):RabbitMQ集群搭建

集群 官方参考文档&#xff1a;https://www.rabbitmq.com/clustering.html RabbitMQ这款消息队列中间件产品本身是基于Erlang编写&#xff0c;Erlang语言天生具备分布式特性&#xff08;通过同步Erlang集群各节点的magic cookie来实现&#xff09;。因此&#xff0c;RabbitMQ天…

什么是柔性玻璃?

柔性玻璃(Flexible glass)是一种新型薄膜玻璃基板(Thin film glass substrate)材料&#xff0c;厚度极薄可以弯曲。 柔性玻璃定义有广义和狭义之分&#xff1a; 广义柔性玻璃泛指所有制成微米尺寸具有可弯曲特性的玻璃材料&#xff0c;如玻璃纤维、光纤、玻璃棉、玻璃布等。这些…

第10课【STM32 USB通讯协议实战】HID键盘+CDC虚拟串口组合设备

目录 前言USB设备类别未定义设备设备描述符/配置描述符分析如何配置从机类型如何配置设备专用的描述符如何配置从机端点 HID设备特点设备描述符/配置描述符分析HID报文描述符短条目前缀可选数据表现形式 层次结构实例分析总结 CDC设备特点设备描述符/配置描述符分析设备类特定请…

【LED子系统】四、核心层详解(一)

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;嵌入式领域新星创作者 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 文章目录 1、前言2、leds_init分析2.1 相关数据结构2.1.1 class 2.2 实现流程 3、leds_class_dev_pm_ops分析…

Mysql出现问题:ERROR 1062 (23000): Duplicate entry ‘‘ for key ‘PRIMARY‘解决方案

回城传送–》《数据库问题解决方案》 ❤️作者主页:小虚竹 ❤️作者简介:大家好,我是小虚竹。Java领域优质创作者🏆,CSDN博客专家🏆,华为云享专家🏆,掘金年度人气作者🏆,阿里云专家博主🏆,51CTO专家博主🏆 ❤️技术活,该赏 ❤️点赞 👍 收藏 ⭐再看,养成…