当前位置: 首页 > news >正文

WPF 几种绑定 (笔记)

资源与绑定DataContext(绑定到我们定义的属性)

xmlns:local="clr-namespace:模板"<Grid>
<Grid.Resources><local:MyViewModel x:Key="SharedViewModel"/>
</Grid.Resources></Grid>

以上仅仅是代表放了一个 "ViewModel 字典

完整引用 是"模板\MyViewModel\SharedViewModel" 然后并没有去使用它

<Grid.DataContext><Binding Source="{StaticResource SharedViewModel}"/>
</Grid.DataContext>

然后要想使用它就得通过指定" Source="{StaticResource SharedViewModel}" 这样就表示Grid绑定上下文对象是我资源定义的"SharedViewModel",这样一来Grid里面的子控件都能去访问到资源"SharedViewModel"里面的内容。

而"StaticResource "标注这个是一个静态绑定 加载后不会再次去加载了也就是上下文都用的同一个"SharedViewModel",在grid里面所有的控件共享一个 "SharedViewModel"资源.

单独互相不干扰的绑定(DataContext)

    <Grid><Grid.ColumnDefinitions><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition/><RowDefinition/></Grid.RowDefinitions><TextBlock x:Name="tex" Text="{Binding DateTimeProperty, StringFormat=yyyy-MM-dd}" ><TextBlock.DataContext><local:MyViewModel/></TextBlock.DataContext></TextBlock><DatePicker Grid.Row="1"SelectedDate="{Binding DateTimeProperty, Mode=TwoWay}" ><DatePicker.DataContext><local:MyViewModel/></DatePicker.DataContext></DatePicker></Grid>

上面实在Grid里面放了一个 "DatePicker"用于选择日期,"TextBlock "显示选择的内容,而且两个控件都绑定了"<local:MyViewModel/>" 这样就代表每次都是绑定一个新的"MyViewModel"对象,就像每次都去new一个对象。所有虽然他们两个直接是双向绑定但是 由于绑定的"MyViewModel"不是同一个所有运行后修改日期 上边的TextBlock 内容并不会变化。

  <Grid.DataContext><local:MyViewModel/></Grid.DataContext><TextBlock x:Name="tex" Text="{Binding DateTimeProperty, StringFormat=yyyy-MM-dd}" ></TextBlock><DatePicker Grid.Row="1"SelectedDate="{Binding DateTimeProperty, Mode=TwoWay}" ></DatePicker>

但是只需要小修改一下让Grid去绑定一个新的"MyViewModel"这样每次就能实现"Grid"子控件和Grid绑定的对象都是同一个"MyViewModel"。虽然这样也能绑定并能每次显示值变化,但是这样每次绑定都会重新去NEW一个"MyViewModel"对象。可以在"MyViewModel"构造函数打上断点就可以看出。

 Text="{Binding DateTimeProperty, StringFormat=yyyy-MM-dd}" >里面的DateTimeProperty是一个MyViewModel类里面的一个属性,类型是日期时间类型,后边跟着的StringFormat=yyyy-MM-dd就表示格式化

要想把控件属性绑定到我们自定义属性就直接用Binding(前提是我们要提前引用资源)

绑定到控件属性(重写类型转换)(ElementName)

 <TextBox Grid.Row="1"FontSize="22"Text="{Binding ElementName=slider,Path=Value,Mode=OneWayToSource}" ></TextBox>
<Sliderx:Name="slider"Grid.Row="0"Maximum="10"Minimum="0"SmallChange="1" />
表达方式实际含义
TextBox → SliderTextBox 是 数据源(Source),Slider 是 目标(Target)

上面我定义两个控件,滑块的value绑定到 txtbox的text上面

Text="{Binding ElementName=slider, Path=Value, Mode=TwoWay}" 

ElementName=slider:类型

Path=Value:要绑定到什么属性

Mode=TwoWay: 绑定模式

Mode说明
OneWaySource → Target(单向)
TwoWaySource ⇄ Target(双向)
OneWayToSourceTarget → Source(反向单向)
OneTimeSource → Target(只在加载时绑定一次)

 总的来说我的理解是ElementName 里面可以去按照x:name定义的名称拿到对应的控件,再通过path属性指定控件的属性,这样来完成控件属性到控件属性的绑定(要把控件的属性帮到拎一个控件上面用它就对了)

 我们来试一下OneWayToSource

<TextBoxGrid.Row="1"FontSize="22"Text="{Binding ElementName=slider, Path=Value, Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged}"/><Sliderx:Name="slider"Grid.Row="0"Maximum="10"Minimum="0"SmallChange="1" />

咋一看好像就是我们拖动滑块 数字不变化,而我们文本框输入后滑块变化这个功能,确实也能运行,但是会出现报错,因为我们滑块的value可以是int也可以是小数类型。而text的值是字符串没有进行转换会出现类型转换错误

这个时候可以自己重写转换器来实现

 class StringToDoubleConverter : IValueConverter{// TextBox → Sliderpublic object Convert(object value, Type targetType, object parameter, CultureInfo culture){return value?.ToString();}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){if (value is string str && double.TryParse(str, out double result)){return result;}return 0.0; // 默认值}}

我们做了一个简单判断如果是字符串并且能够转换成double我们把字符串转换位double,接下来看我们如何使用它。

       <Grid.Resources><local:StringToDoubleConverter x:Key="StrToDoubleConverter2"/><local:MyViewModel x:Key="MyViewModel"/></Grid.Resources><TextBox Grid.Row="1"FontSize="22"Text="{Binding ElementName=slider,Path=Value,Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource StrToDoubleConverter2}}" ></TextBox><Sliderx:Name="slider"Grid.Row="0"Maximum="10"Minimum="0"SmallChange="1" />

我先是定义两个资源 

<local:StringToDoubleConverter x:Key="StrToDoubleConverter2"/>
           <local:MyViewModel x:Key="MyViewModel"/>

接着用 Converter={StaticResource StrToDoubleConverter2}}" 去绑定我写的类型转换,这样就达到了想要的效果

  UpdateSourceTrigger=PropertyChanged:比较特殊,可以把这条删除再看看是不是输入字符串后滑块不改变了,当你离开文本框后滑块值才发送改变。(当然也可以 UpdateSourceTrigger=PropertyChanged,Delay=1000,加点延迟)

触发时机描述适用场景
PropertyChanged属性值每变化一次就更新源实时联动、搜索、滑块绑定
LostFocus(默认)只有失去焦点才更新一般表单输入、性能优化
Explicit需要代码显式调用更新貌似我用不上

绑定当中的 (Source )属性介绍

  <TextBlock Text="{Binding DateTimeProperty, Source={StaticResource MyViewModel}}" /><TextBlock Text="{Binding DateTimeProperty}" DataContext="{Binding }"/>

这里需要特别注意 第一节绑定是

{Binding DateTimeProperty, Source={StaticResource MyViewModel}}" 多个参数绑定 逗号隔开

第二节 绑定是"{Binding DateTimeProperty}" DataContext="{Binding }" 不同属性或绑定 空格隔开

Source 可以不依靠DataContext,跳过它并绑定到任意Source 指定的对象属性上,准确说就是忽略 DataContext直接绑定到资源名为 MyViewModel 的对象的 DateTimeProperty 属性。

总结 当你的上下文绑定不再满足你要求 ,想绑定,非DataContext里面的属性就用 Source去指定来绑定。

绑定到上级属性(RelativeSource)

<TextBlock Background="{Binding Path=Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}}" Text="1213" />

这个绑定和之前控件属性与控件属性绑定又点类似

1.指定绑定的属性"Binding Path=Background"

2.RelativeSource源设定:RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel}//是从什么类型绑定过来,通过查找祖先元素

Mode=FindAncestor:向上查找祖先元素

AncestorType=StackPanel:查找的类型是StackPanel

这样就会一级一级往上找找到最近的一个满足要求的绑定上去

自己的另一个属性RelativeSource Self
上层容器(如 Grid, Window)RelativeSource AncestorType=XXX
模板中绑定外部控件的属性RelativeSource TemplatedParent
上一个数据项(ItemsControl 场景)RelativeSource PreviousData

最后两种貌似现在我还没学到控件模板看视频应该后边控件模板绑定会用到先记录下来把!

相关文章:

  • 乐清建设路小学校园网站seo标题优化裤子关键词
  • seo关键词优化软件排名赣州seo优化
  • 做网站服务器收费吗山东16市最新疫情
  • 单页静态网站怎么做什么是seo站内优化
  • 东莞兼职招聘网最新招聘湖南网站优化
  • 网站做全局搜索网络营销薪酬公司
  • Docker 安装与配置 详解——AI教你学Docker
  • 实物建模性能优化秘籍:如何将模型面数减少且保持质感
  • 实现OFD转换PDF文件的实用方法
  • 计算机基础和Java编程的练习题
  • (LeetCode 每日一题) 2200. 找出数组中的所有 K 近邻下标 (双指针)
  • CasaOS中Docker部署SyncThing结合Cpolar实现公网文件同步方案
  • Kafka 监控与调优实战指南(二)
  • 华为云Flexus+DeepSeek征文 | 华为云MaaS平台上的智能客服Agent开发:多渠道融合应用案例
  • 《高并发系统的一致性保障:RocketMQ事务消息实现原理与应用》
  • JAVA的springboot项目使用AliMQ示例
  • vftp centos 离线部署
  • 【深度学习】-学习篇(一)
  • 纪念抗战胜利知识答题pk小程序
  • 【JS-4.8-type属性】深入理解DOM操作中的type属性及其常见应用
  • Python爬虫结合API接口批量获取PDF文件
  • Dify全面升级:打造极致智能应用开发体验,携手奇墨科技共拓AI新生态
  • 鸿蒙应用开发中的状态管理:深入解析AppStorage与LocalStorage
  • log4cplus调用
  • 《仿盒马》app开发技术分享-- 兑换商品详情(69)
  • WPF中的MVVM设计模式