当前位置: 首页 > 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

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

http://www.lryc.cn/news/574556.html

相关文章:

  • maven:迁移到 Maven Central 后 pom.xml的配置步骤
  • pdf转图片(png,jpg)的python脚本
  • 发布 npm 包完整指南(含账号注册、发布撤销与注意事项)
  • 【云计算】云测试
  • 成交量流动策略
  • Unity3D仿星露谷物语开发70之背景音乐
  • 软件测试报告机构如何保障软件质量与安全性?作用有哪些?
  • 使用 PyFluent 自动化 CFD
  • 用 Python 打造立体数据世界:3D 堆叠条形图绘制全解析
  • 【Pandas】pandas DataFrame update
  • 华为云Flexus+DeepSeek征文 | 华为云MaaS平台上的智能客服Agent开发:多渠道融合应用案例
  • 《C++初阶之类和对象》【初始化列表 + 自定义类型转换 + static成员】
  • 在 centos7部署kubephere
  • TortoiseSVN 安装教程
  • prometheus+grafana+MySQL监控
  • 云原生周刊:Argo CD v3.1 正式发布
  • 工程优化——WebSocket、WSS(WebSocket Secure)和SSE(Server-Sent Events)通信对比
  • Jenkins+Jmeter+Ant接口持续集成
  • 【人工智能agent】--dify实现文档内容的自动抽取
  • 论文阅读:2025 arxiv Qwen3 Technical Report
  • 【论文阅读 | CVPRW 2023 |CSSA :基于通道切换和空间注意力的多模态目标检测】
  • 【AI时代速通QT】第三节:Linux环境中安装QT并做测试调试
  • Starrocks 低基数全局字典优化
  • 【Vue】 keep-alive缓存组件实战指南
  • Dify携手代理商奇墨科技:加快企业AI应用构建
  • FTP原理、安装部署与案例应用全面指南
  • Unity3D下的RTSP/RTMP超低延迟直播播放器实践:跨平台、高性能与VR全景支持的完整解析
  • 创建首个 Spring Boot 登录项目
  • DD3118S:USB3.0+Type-c双头TF/SD二合一高速0TG多功能手机读卡器ic
  • 76、单元测试-参数化测试