在99.999975%的情形下,可视化元素之间的相互绑定都会在同一个容器中完成,如同一个窗口,同一个UserControl等。但在极少数的情况下,为了从最大限度减少代码赋值的前提下考虑,是可以使用跨窗口绑定。

比如窗口A中有一个控件XA,B窗口中有个YB控件,我希望把A中的XA控件的Text属性与B中的YB控件的Item属性进行绑定。绑定后的好处在于,当Item属性更新后,会自动修改Text属性,而不需要额外写代码去监视各控件属性的更改。因为高境界程序员向来都是以最少的代码做最多的事情。

然而,在默认情况下,一个窗口的代码是不能访问另一个窗口中的控件的,XAML文档中声明的控件变量默认的访问方式为private。为了解决这一局限,XAML的扩展标记中提供了FieldModifier扩展,可以修改XAML文档中声明对象的访问方式。比如这样:

        <TextBlock Name="tbtxt" x:FieldModifier="public" />

通过设置x:FieldModifier="public",使得名为tbtxt的TextBlock控件会被生成为public字段,这么一来,其他的窗口就可以访问该控件了。

只有解决了上述问题,才能实现控件的跨窗口绑定。

为了使本文的内容变得生动活泼,充满青春活力,接下来老周会举一个500年不遇的简单例子。

本示例包含两个窗口,主窗口为MainWindow类,外加一个自定义窗口MyDialog(当作自定义对话框)。主窗口中有一个TextBlock控件和一个Button控件,当点击按钮后会打开MyDialog对话框,对话框中有一个ComboBox控件,当用户在ComboBox控件中选择项时,会同步更新主窗口中TextBlock的显示文本。

即,将MainWindow.TextBlock对象的Text属性和MyDialog中的ComboBox控件的SelectedItem属性进行绑定。Text属性自动从SelectedItem属性中取值。

为了让MyDialog窗口能够访问主窗口中的TextBlock对象,所以XAML要这样写:

        <TextBlock Name="tbtxt" x:FieldModifier="public" Margin="10"/>
<Button Content="打开对话框" Click="OnOpenDialog"/>

然后,设计MyDialog的界面,声明ComboBox对象,并添加几个选项。

        <ComboBox Name="cmb" >
<sys:String>飞机</sys:String>
<sys:String>坦克</sys:String>
<sys:String>火车</sys:String>
<sys:String>轮船</sys:String>
<sys:String>大卡车</sys:String>
<sys:String>拖拉机</sys:String>
<sys:String>装甲车</sys:String>
</ComboBox>
<Button HorizontalAlignment="Center" Grid.Row="1" Margin="0,20" Content="OK" Click="OnClick"/>

接着,在MyDialog类的构造函数中通过代码来设置Binding。

        public MyDialog(Window owner)
{
this.Owner = owner;
InitializeComponent(); // 设置Binding对象
Binding b = new Binding();
b.Path = new PropertyPath(ComboBox.SelectedItemProperty);
b.Source = cmb;
b.Mode = BindingMode.OneWay;
b.StringFormat = "您选择的交通工具为:{0}"; MainWindow mw = Owner as MainWindow;
// 使属性与Binding关联
mw?.tbtxt.SetBinding(TextBlock.TextProperty, b);
}

Window类有一个Owner属性,可以设置它的父窗口,这里,MyDialog作为弹出窗口,MainWindow作为父窗口,因此在实例化MyDialog时传递owner,使得代码能访问MainWindow。我这里为了方便省事,直接写了个带参数的构造函数。

注意此处的绑定,数据源是ComboBox控件,数据使用者是TextBlock,所以Binding的Source应为cmb实例,Path直接用依赖项属性标识即可。

最后调用TextBlock对象的SetBinding方法就可以设置Binding了。

为啥不用XAML来binding呢,因为这是跨窗口的绑定,用XAML很难写,用代码来写反而好处理。

运行程序,然后打开对话框,在对话框中选一个项,你会看到,父窗口中的显示文本会自动更新。

准确地说,本文内容不算是什么高科技,纯粹是一种技巧运用吧。示例不需要多复杂,只要能起到演示效果就行,老周天生讨厌把事情复杂化,所以老周的座右铭是:

非Easy无以致学,非实战无以Code。

示例源码下载

【.NET深呼吸】(WPF)跨窗口完成绑定的更多相关文章

  1. WPF 程序如何跨窗口/跨进程设置控件焦点

    原文:WPF 程序如何跨窗口/跨进程设置控件焦点 WPF 程序提供了 Focus 方法和 TraversalRequest 来在 WPF 焦点范围内转移焦点.但如果 WPF 窗口中嵌入了其他框架的 U ...

  2. WPF 在事件中绑定命令(不可以在模版中绑定命令)

    其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是 ...

  3. WPF 在事件中绑定命令

    导航:MVVMLight系列文章目录:<关于 MVVMLight 设计模式系列> 其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实 ...

  4. WPF中,如何将绑定源设置到单件实例

    原文:WPF中,如何将绑定源设置到单件实例  WPF中,如何将绑定源设置到单件实例                                       周银辉 大概两个月前,曾有位朋友问我:如 ...

  5. WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)

    原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程 ...

  6. 官宣|VS Code 1.59 发布!Terminal 可以跨窗口移动了!

    欢迎使用 2021 年 7 月版的 Visual Studio Code.我们希望您会喜欢此版本中的许多更新与改进,以下是其中的一些高亮: 扩展视图的改进 - 丰富的扩展详细信息悬停,新的运行状态标签 ...

  7. 2000条你应知的WPF小姿势 基础篇<74-77 WPF 多窗口Tips>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000ThingsYou Should Know About C# 和 2,00 ...

  8. WPF自定义窗口基类

    WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...

  9. appcan 跨窗口处理方法 appcan.window.evaluateScript({name,scriptContent,type})使用解读

    appcan.window.evaluateScript({ name,/*主窗口名称,此窗口要先用appcan.window.open打开了,才能找到,此方法才会有效*/ scriptContent ...

随机推荐

  1. ASP.NET Core MVC/WebAPi 模型绑定探索

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  2. 菜鸟学Struts2——Interceptors

    昨天学习Struts2的Convention plugin,今天利用Convention plugin进行Interceptor学习,虽然是使用Convention plugin进行零配置开发,这只是 ...

  3. JavaScript 开发规范

    本篇主要介绍JS的命名规范.注释规范以及框架开发的一些问题. 目录 1. 命名规范:介绍变量.函数.常量.构造函数.类的成员等等的命名规范 2. 注释规范:介绍单行注释.多行注释以及函数注释 3. 框 ...

  4. JavaScript的继承实现方式

    1.使用call或apply方法,将父对象的构造函数绑定在子对象上 function A(){ this.name = 'json'; } function B(){ A.call(this); } ...

  5. Android SDK 在线更新镜像服务器资源

    本文转自:http://blog.kuoruan.com/24.html.感谢原作者. 什么是Android SDK SDK:(software development kit)软件开发工具包.被软件 ...

  6. 用django创建一个项目

    首先你得安装好python和django,然后配置好环境变量,安装python就不说了,从配置环境变量开始 1.配置环境变量 在我的电脑处点击右键,或者打开 控制面板\系统和安全\系统 -> 左 ...

  7. Visual Studio:error MSB8020(搬运)

    状况如下: error MSB8020: The builds tools for v120 (Platform Toolset = 'v120') cannot be found. To build ...

  8. 敏捷转型历程 - Sprint3 回顾会

    我: Tech Leader 团队:团队成员分布在两个城市,我所在的城市包括我有4个成员,另外一个城市包括SM有7个成员.另外由于我们的BA离职了,我暂代IT 的PO 职位.PM和我在一个城市,但他不 ...

  9. 基于jQuery左右滑动切换特效 附源码

    分享一款基于脚jQuery左右滑动切换特效.这是一款鼠标点击左右箭头按钮图片滚动切换,鼠标移到图片上显示透明边框特效.   效果图如下:   废话不多说,代码奉上!   html代码: <div ...

  10. HTML5 标签 details 展开 搜索

    details有一个新增加的子标签--summary,当鼠标点击summary标签中的内容文字时,details标签中的其他所有元素将会展开或收缩. 默认状态为 收缩状态 设置为展开状态为 <d ...