zoukankan      html  css  js  c++  java
  • 【.NET深呼吸】(WPF)跨窗口完成绑定

    在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。

    示例源码下载

  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/4947073.html
Copyright © 2011-2022 走看看