《深入浅出WPF》读书笔记.6binding系统(中)

news2024/9/21 4:20:06

《深入浅出WPF》读书笔记.6binding系统(中)

背景

这章主要讲各种模式的数据源和目标的绑定。

代码

把控件作为Binding源与Binding标记扩展

方便UI元素之间进行关联互动

<Window x:Class="BindingSysDemo.BindingEle"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="BindingEle" Height="300" Width="400">
    <Grid>
        <Canvas>
            <TextBox x:Name="tb1" Text="{Binding ElementName=slider1, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200"
                     Canvas.Left="100" Canvas.Top="117" HorizontalAlignment="Center" VerticalAlignment="Top"></TextBox>
            <Slider x:Name="slider1" Maximum="100" Minimum="0" Canvas.Left="100" Canvas.Top="142" Width="200" 
                    RenderTransformOrigin="0.5,-0.069" HorizontalAlignment="Center" VerticalAlignment="Top"
                    Value="50"/>
            <Button x:Name="btn" Content="失去焦点" Width="120" Canvas.Left="140" Canvas.Top="165"></Button>
        </Canvas>
    </Grid>
</Window>


控制Binding的方向及数据更新

Mode:

TwoWay:双向

OneWay:单向(source到target)

OneTime:一次(source到target)

OneWayToSource:单向(Target到source)

Default:看情况随机调整


Binding的路径(Path)

使用binding path来指定所关注的属性值

<Window x:Class="BindingSysDemo.ListPathDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"QA
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="ListPathDemo" Height="300" Width="400">
    <Grid>
        <StackPanel>
            <StackPanel.Resources>
                <sys:String x:Key="myStr">
                    菩提本无树,明镜亦非台
                </sys:String>
            </StackPanel.Resources>
            <TextBox x:Name="tb1"></TextBox>
            <TextBox x:Name="tb2"></TextBox>
            <TextBox x:Name="tb3"></TextBox>
            <TextBox x:Name="tbNopath" Text="{Binding Path=.,Source={StaticResource ResourceKey=myStr}}"></TextBox>
        </StackPanel>
        
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BindingSysDemo
{
    /// <summary>
    /// ListPathDemo.xaml 的交互逻辑
    /// </summary>
    public partial class ListPathDemo : Window
    {
        public ListPathDemo()
        {
            InitializeComponent();
            //List<string> strList = new List<string>() { "Tim", "Tom", "John" };
            //this.tb1.SetBinding(TextBox.TextProperty, new Binding("/") { Source = strList });
            //this.tb2.SetBinding(TextBox.TextProperty, new Binding("/Length") { Source = strList, Mode = BindingMode.OneWay });
            //this.tb3.SetBinding(TextBox.TextProperty, new Binding("/[2]") { Source = strList, Mode = BindingMode.OneWay });

            List<Country> countryList = new List<Country>(){new Country()
            {
                Name = "美国",
                ProvinceList = new List<Province> { new Province { Name="德克萨斯洲",CityList=new List<City>
            {
                new City{Name="纽约"},
                new City{Name="哈萨克"}
            } } }
            } };
            this.tb1.SetBinding(TextBox.TextProperty, new Binding("/Name") { Source = countryList });
            this.tb2.SetBinding(TextBox.TextProperty, new Binding("/ProvinceList/Name") { Source = countryList, Mode = BindingMode.OneWay });
            this.tb3.SetBinding(TextBox.TextProperty, new Binding("/ProvinceList/CityList/Name") { Source = countryList, Mode = BindingMode.OneWay });
        }
    }
    class City
    {
        public string Name { get; set; }
    }

    class Province
    {
        public string Name { get; set; }
        public List<City> CityList { get; set; }
    }

    class Country
    {
        public string Name { get; set; }
        public List<Province> ProvinceList { get; set; }
    }
}


“没有Path”的Binding

binding源本身就是数据,Path=.指定自身

<Window x:Class="BindingSysDemo.ListPathDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="ListPathDemo" Height="300" Width="400">
    <Grid>
        <StackPanel>
            <StackPanel.Resources>
                <sys:String x:Key="myStr">
                    菩提本无树,明镜亦非台
                </sys:String>
            </StackPanel.Resources>
            <TextBox x:Name="tb1"></TextBox>
            <TextBox x:Name="tb2"></TextBox>
            <TextBox x:Name="tb3"></TextBox>
            <TextBox x:Name="tbNopath" Text="{Binding Path=.,Source={StaticResource ResourceKey=myStr}}"></TextBox>
        </StackPanel>
        
    </Grid>
</Window>


为Binding指定源(Source)的几种方法


没有Source的BindingDatataContext作为Binding的源

DataContext做为依赖属性当控件底层元素没有设置dataconetxt时会向下传递。看起来像在一层一层向上找。

<Window x:Class="BindingSysDemo.DataContextDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="DataContextDemo" Height="300" Width="400">
    <StackPanel Background="LightBlue">
        <StackPanel.DataContext>
            <local:Employee Id="1" Age="20" Name="Jack"></local:Employee>
        </StackPanel.DataContext>
        <Grid>
        <StackPanel>
            <TextBox Text="{Binding Path=Id}" Margin="5"></TextBox>
            <TextBox Text="{Binding Path=Name}" Margin="5"></TextBox>
            <TextBox Text="{Binding Path=Age}" Margin="5"></TextBox>
        </StackPanel>
    </Grid>
    </StackPanel>
</Window>


使用集合对象作为列表控件的 ItemsSource

在使用集合类型作为列表控件的ItemsSource 时一般会考虑使用ObservableCollection<T>代替
List<T>,因为ObservableCollection<T>类实现了INotifyCollectionChanged和INotifyPropertyChanged接口,能把集合的变化
立刻通知显示它的列表控件,改变会立刻显现出来,

<Window x:Class="BindingSysDemo.ItemSourceDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="ItemSourceDemo" Height="300" Width="400">
    <Grid>
        <StackPanel x:Name="sp1" Background="LightBlue">
            <TextBlock Text="Employee ID:" Margin="5"></TextBlock>
            <TextBox x:Name="tbId" Margin="5"></TextBox>
            <TextBlock x:Name="tblId" Margin="5" Text="Employee List:"></TextBlock>
            <ListBox x:Name="listBoxEmployee" Height="150" Margin="5">
                <!--在xaml中适用DataTemplate-->
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding Path=Id}" Width="120"></TextBlock>
                            <TextBlock Text="{Binding Path=Name}" Width="120"></TextBlock>
                            <TextBlock Text="{Binding Path=Age}" Width="120"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BindingSysDemo
{
    /// <summary>
    /// ItemSourceDemo.xaml 的交互逻辑
    /// </summary>
    public partial class ItemSourceDemo : Window
    {
        public ItemSourceDemo()
        {
            InitializeComponent();
            List<Employee> employees = new List<Employee>()
            {
                new Employee(){Id=1,Name="Tom",Age="20" },
                new Employee(){Id=2,Name="Shoyn",Age="20" },
                new Employee(){Id=3,Name="Timi",Age="20" },
                new Employee(){Id=4,Name="Jack",Age="20" }
            };
            this.listBoxEmployee.ItemsSource = employees;
            //在listBox获取ItemsSource后会以DisplayMemberPath创建binding
            //this.listBoxEmployee.DisplayMemberPath = "Name";
            Binding binding = new Binding("SelectedItem.Id") { Source = this.listBoxEmployee, 
                Mode = BindingMode.OneWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
            this.tbId.SetBinding(TextBox.TextProperty, binding);
        }
    }
}


使用ADO.NET对象作为Binding的源

正常使用dataview用来binding,当datatable放在datacontext中时,可以自动选找到datable的defaultview进行绑定

<Window x:Class="BindingSysDemo.DatatableDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="DatatableDemo" Height="300" Width="400">
    <Grid>
        <StackPanel Background="AliceBlue">
            <ListView x:Name="listView1" Height="250" Margin="5">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Id" Width="80" DisplayMemberBinding="{Binding Id}"></GridViewColumn>
                        <GridViewColumn Header="Name" Width="80" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
                        <GridViewColumn Header="Age" Width="80" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <Button x:Name="btn1" Click="btn1_Click" Content="点击一下" Width="120"></Button>
        </StackPanel>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BindingSysDemo
{
    /// <summary>
    /// DatatableDemo.xaml 的交互逻辑
    /// </summary>
    public partial class DatatableDemo : Window
    {
        public DatatableDemo()
        {
            InitializeComponent();
        }

        private void btn1_Click(object sender, RoutedEventArgs e)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Age", typeof(string));

            for (int i = 0; i < 5; i++)
            {
                DataRow dataRow = dt.NewRow();
                dataRow["Id"] = i;
                dataRow["Name"] = "Name" + i.ToString();
                dataRow["Age"] = 20 + i;
                dt.Rows.Add(dataRow);
            }

            this.listView1.ItemsSource = dt.DefaultView;
            this.listView1.DisplayMemberPath = "Name";
        }
    }
}


使用XML数据作为Binding的源

使用xpath而不是path

<Window x:Class="BindingSysDemo.XmlSourceBindingDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="XmlSourceBindingDemo" Height="400" Width="400">
    <StackPanel>
        <ListView x:Name="listView1" Height="300" Margin="5">
            <ListView.View>
                <GridView>
                    <!--@Id表示xml元素的attribute Id Name则代表子级元素 -->
                    <GridViewColumn Header="Id" Width="120" DisplayMemberBinding="{Binding XPath=@Id}"></GridViewColumn>
                    <GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding XPath=Name}"></GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
        <Button x:Name="btn1" Content="添加数据" Width="120" Click="btn1_Click"></Button>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;

namespace BindingSysDemo
{
    /// <summary>
    /// XmlSourceBindingDemo.xaml 的交互逻辑
    /// </summary>
    public partial class XmlSourceBindingDemo : Window
    {
        public XmlSourceBindingDemo()
        {
            InitializeComponent();
        }

        private void btn1_Click(object sender, RoutedEventArgs e)
        {
            XmlDocument xmlDocument = new XmlDocument();
            string xmlPath = AppDomain.CurrentDomain.BaseDirectory + "StudentList.xml";
            xmlDocument.Load(xmlPath);
            XmlDataProvider xdp = new XmlDataProvider();
            //xdp.Document = xmlDocument;
            xdp.Source=new Uri(xmlPath);
            xdp.XPath = @"/StudentList/Student";

            this.listView1.DataContext = xdp;
            this.listView1.SetBinding(ListView.ItemsSourceProperty, new Binding());

        }
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<StudentList>
	<Student Id="1">
		<Name>Tom</Name>
		<Age>20</Age>
	</Student>
	<Student Id="2">
		<Name>Tim</Name>
		<Age>20</Age>
	</Student>
	<Student Id="3">
		<Name>Jack</Name>
		<Age>20</Age>
	</Student>
	<Student Id="4">
		<Name>john</Name>
		<Age>20</Age>
	</Student>
	<Student Id="5">
		<Name>Mark</Name>
		<Age>20</Age>
	</Student>
</StudentList>

层级结构

<Window x:Class="BindingSysDemo.HierarchicalDataTplDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="HierarchicalDataTplDemo" Height="400" Width="400">
    <Window.Resources>
        <XmlDataProvider x:Key="xdp" XPath="FileSystem/Forder">
            <x:XData>
                <FileSystem xmlns="">
                    <Forder Name="Books">
                        <Forder Name="Programming">
                            <Forder Name="Windows">
                                <Forder Name="WPF"></Forder>
                                <Forder Name="MFC"></Forder>
                                <Forder Name="Dephi"></Forder>
                            </Forder>
                        </Forder>
                        <Forder Name="Tools">
                            <Forder Name="Developmentg"></Forder>
                            <Forder Name="Designment"></Forder>
                            <Forder Name="Players"></Forder>
                        </Forder>
                    </Forder>
                </FileSystem>
            </x:XData>
        </XmlDataProvider>
    </Window.Resources>
    <Grid>
        <TreeView ItemsSource="{Binding Source={StaticResource xdp}}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding XPath=Forder}">
                    <TextBlock Text="{Binding XPath=@Name}"></TextBlock>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>


使用LINQ检查结果作为Binding的源

<Window x:Class="BindingSysDemo.LinqBindingDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="LinqBindingDemo" Height="400" Width="400">
    <Grid>
        <StackPanel Background="AliceBlue">
            <ListView x:Name="listView1" Height="250" Margin="5">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Id" Width="80" DisplayMemberBinding="{Binding Id}"></GridViewColumn>
                        <GridViewColumn Header="Name" Width="80" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
                        <GridViewColumn Header="Age" Width="80" DisplayMemberBinding="{Binding Age}"></GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <Button x:Name="btn1" Click="btn1_Click" Content="点击一下" Width="120"></Button>
        </StackPanel>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;

namespace BindingSysDemo
{
    /// <summary>
    /// LinqBindingDemo.xaml 的交互逻辑
    /// </summary>
    public partial class LinqBindingDemo : Window
    {
        public LinqBindingDemo()
        {
            InitializeComponent();
        }

        private void btn1_Click(object sender, RoutedEventArgs e)
        {
            //操作List
            //List<Employee> employees = new List<Employee>()
            //{
            //    new Employee(){Id=1,Name="Tom",Age="20" },
            //    new Employee(){Id=2,Name="Shoyn",Age="20" },
            //    new Employee(){Id=3,Name="Timi",Age="20" },
            //    new Employee(){Id=4,Name="Jack",Age="20" }
            //};
            //this.listView1.ItemsSource = from stu in employees where stu.Name.Contains("T") select stu;
            XDocument xmlDoc = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "StudentList2.xml");
            //适用linq操作xml Descendants可以跨越层级
            this.listView1.ItemsSource = from eml in xmlDoc.Descendants("Student")
                                         where eml.Attribute("Name").Value.StartsWith("T")
                                         select new Employee
                                         {
                                             Id = int.Parse(eml.Attribute("Id").Value),
                                             Name = eml.Attribute("Name").Value,
                                             Age = eml.Attribute("Age").Value
                                         };

        }
    }
}


使用ObjectDataProvider对象作为Binding的Source

当不想暴漏类对象的全部属性值,或者想使用方法返回值作为绑定值时

<Window x:Class="BindingSysDemo.ObjectDataProviderDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="ObjectDataProviderDemo" Height="400" Width="400">
    <StackPanel Background="AliceBlue">
        <TextBox x:Name="tbArg1" Margin="5"></TextBox>
        <TextBox x:Name="tbArg2" Margin="5"></TextBox>
        <TextBox x:Name="tbRes" Margin="5"></TextBox>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BindingSysDemo
{
    /// <summary>
    /// ObjectDataProviderDemo.xaml 的交互逻辑
    /// 当只想暴漏部分属性的时候
    /// </summary>
    public partial class ObjectDataProviderDemo : Window
    {
        public ObjectDataProviderDemo()
        {
            InitializeComponent();
            this.SetBinding();
        }

        private void SetBinding()
        {
            ObjectDataProvider odp = new ObjectDataProvider();
            //让ObjectDataProvider自行创建对象
            //odp.ObjectType = typeof(Calculator);
            odp.ObjectInstance = new Calculator();
            odp.MethodName = "Add";
            //ObjectDataProvider通过参数数量来区分重载方法
            //MethodParameters并非依赖属性
            odp.MethodParameters.Add("0");
            odp.MethodParameters.Add("0");

            Binding binding2Arg1 = new Binding("MethodParameters[0]")
            {
                Source = odp,
                //直接写若obp对象而不是Calculator
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };

            Binding binding2Arg2 = new Binding("MethodParameters[1]")
            {
                Source = odp,
                BindsDirectlyToSource = true,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            };
            Binding binding2Res = new Binding(".") { Source = odp };

            this.tbArg1.SetBinding(TextBox.TextProperty, binding2Arg1);
            this.tbArg2.SetBinding(TextBox.TextProperty, binding2Arg2);
            this.tbRes.SetBinding(TextBox.TextProperty, binding2Res);

        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BindingSysDemo
{
    public class Calculator
    {
        public string Add(string arg1, string arg2)
        {
            double x = 0;
            double y = 0;
            double z = 0;
            if (double.TryParse(arg1, out x) && double.TryParse(arg2, out y))
            {
                z = x + y;
                return z.ToString();
            }
            return "Input Error!";
        }
    }
}


使用Binding的RelativeSource

不确定数据来源,但在UI层级上有关系时使用

<Window x:Class="BindingSysDemo.RelativeSouceDemo"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingSysDemo"
        mc:Ignorable="d"
        Title="RelativeSouce" Height="400" Width="400">
    <Grid x:Name="g1" Background="Red" Margin="10">
        <DockPanel x:Name="d1" Background="Orange" Margin="10">
            <Grid x:Name="g2" Background="Yellow" Margin="10">
                <DockPanel x:Name="d2" Background="LawnGreen" Margin="10">
                    <TextBox x:Name="tb1" FontSize="24" Margin="10"
                             Text="{Binding RelativeSource={RelativeSource AncestorLevel=2 ,AncestorType={x:Type Grid}},Path=Name}"></TextBox>
                </DockPanel>
            </Grid>
        </DockPanel>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BindingSysDemo
{
    /// <summary>
    /// RelativeSouce.xaml 的交互逻辑
    /// 当不知道source是什么,但清楚其与binding的目标对象有层级关系时
    /// </summary>
    public partial class RelativeSouceDemo : Window
    {
        public RelativeSouceDemo()
        {
            InitializeComponent();

            /*RelativeSource rs =new RelativeSource(RelativeSourceMode.FindAncestor);//RelativeSourceMode.Self 绑定自身属性

            //从当前层向上找到第二个Grid
            rs.AncestorLevel = 2;
            rs.AncestorType = typeof(Grid);

            Binding binding = new Binding("Name") { RelativeSource = rs };
            this.tb1.SetBinding(TextBox.TextProperty, binding);*/
        }
    }
}

git地址

GitHub - wanghuayu-hub2021/WpfBookDemo: 深入浅出WPF的demo


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

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

相关文章

IP打开“向下”空间,爱奇艺“摊牌了”

长视频领域上半年竞争激烈、好剧频出&#xff0c;让行业焕发了新的吸引力&#xff0c;优质内容对行业的正向引导作用持续凸显。正如爱奇艺创始人、CEO龚宇最新的发言&#xff1a;“长视频行业实现长期发展的关键在于优质内容供给的持续性&#xff0c;以及内容质量和商业收益的双…

页面设计任务 商品详情页

目录 成品: 任务描述 源码&#xff1a; 详细讲解&#xff1a; 1.导航栏讲解 2.主体部分 3.图像部分 4.评分部分 5.按钮部分 6.配置信息部分 7.响应式设计 成品: 任务描述 创建一个产品展示页面&#xff0c;包括以下内容&#xff1a; 网页结构&#xff1a;使用 HTM…

选择适合的电脑监控软件,可以提升员工效率

在信息化时代&#xff0c;企业对员工的管理不再仅限于传统的考勤制度和绩效评估。随着工作方式的多样化&#xff0c;特别是远程办公的普及&#xff0c;电脑监控软件成为企业管理的重要工具。这些软件不仅能帮助管理者了解员工的工作状态&#xff0c;还能有效提升工作效率&#…

唯有自救,才能得救

回顾这一周的五天&#xff0c;也做成了一些事&#xff0c;想做的事&#xff0c;立即行动&#xff0c;几乎是心到手到&#xff0c;最后也出了一些成绩。 全红婵跳完水&#xff0c;得了个满分&#xff0c;一边走路&#xff0c;一边擦头发&#xff0c;旁边的记者问&#xff1a;你…

数字孪生网络 (DTN)关键技术分析

数字孪生网络 (DTN): 概念、架构及关键技术 摘要 随着5G商用规模部署和下一代互联网IPv6的深化应用&#xff0c;新一代网络技术的发展引发了产业界的广泛关注。智能化被认为是新一代网络发展的趋势&#xff0c;为数字化社会的信息传输提供了基础。面向数字化、智能化的新一代网…

Leetcode面试经典150题-42.接雨水

解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {/**本题的解题思路是双指针&#xff1a;一个从头开始一个从尾巴开始&#xff0c;两头的肯定是没有办法接住雨水的,你可以认为0位置左边是0的柱子所以理论上我们是从1遍历到n-2&#xff0c;但是你也可以遍历0到N…

SpringData基础学习

一、SpringData 概述 二、SpringData JPA HelloWorld 三、Repository 接口

快速入门:使用Python构建学生成绩管理应用

前言 诸位观众&#xff0c;本学期我有幸学习了Python编程课程。随着课程的结束&#xff0c;授课教师布置了一项任务&#xff0c;要求我们开发一个学生信息管理系统。基于老师的要求&#xff0c;我个人独立完成了这项任务。今天&#xff0c;我希望将这个简易的程序分享给大家&a…

《黑神话·悟空》是用什么编程语言开发的?

最近国内出了一款3A大作的游戏&#xff0c;凭借牛b的画面、文化底蕴、剧情&#xff0c;已经吸引了很多人入局&#xff0c;当然小孟也在第一时间尝鲜。 最直接的感受&#xff1a;效果牛b&#xff0c;画面牛b&#xff0c;游戏好玩。但是时间太忙&#xff0c;准备过年的放假的时候…

PMP–知识卡片--鱼骨图

鱼骨图由日本质量管理大师石川馨发明&#xff0c;也称因果图&#xff0c;原本用于质量管理。现在多用于问题整理。 在使用该工具时&#xff0c;把问题写在鱼骨的头上&#xff0c;然后召集同事&#xff0c;尽可能多的找出问题&#xff0c;大骨写大问题&#xff0c;中小骨写中小…

Web前端性能优化合集

简介 自互联网兴起以来&#xff0c;从最初的静态网页到如今的动态交互、单页应用&#xff08;SPA&#xff09;、PWA&#xff08;Progressive Web Apps&#xff09;等&#xff0c;互联网技术正在飞速发展&#xff0c;随着用户体验成为核心竞争力之一&#xff0c;前端性能直接影…

哪种电容笔更好用一点?2024开学季实测五款高性价比电容笔!

近年来&#xff0c;随着无纸化学习的日益普及&#xff0c;电容笔的重要性越来越凸显&#xff0c;但面对市场上数不清的电容笔种类和品牌&#xff0c;我们到底该选择哪种电容笔更好用一点呢&#xff1f;趁着即将开学&#xff0c;好多小伙伴都在寻找学习用品和数码好物之际&#…

Python Selenium实现自动化测试及Chrome驱动使用!

本文将介绍如何使用Python Selenium库实现自动化测试&#xff0c;并详细记录了Chrome驱动的使用方法。 通过本文的指导&#xff0c;读者将能够快速上手使用Python Selenium进行自动化测试。 并了解如何配置和使用Chrome驱动来实现更高效的自动化测试。 一、Python Selenium简…

2024年甘肃省安全员C证证考试题库及甘肃省安全员C证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年甘肃省安全员C证证考试题库及甘肃省安全员C证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

运动耳机哪个牌子好?五大高品质巅峰机型汇总!

​对于运动时享受音乐的朋友来说&#xff0c;耳机的舒适度至关重要&#xff0c;它直接影响到我们能否在运动中发挥最佳状态。无论是高端旗舰耳机还是性价比较高的入门级产品&#xff0c;长时间佩戴的不适感都可能干扰我们的运动节奏。因此&#xff0c;开放式耳机因其不入耳的设…

数据资产价值评价:开启数据要素市场的关键钥匙

数据资产价值评价&#xff1a;开启数据要素市场的关键钥匙 前言数据资产价值评价 前言 数据资产作为当今数字化时代的重要生产要素&#xff0c;其价值评价至关重要。数据资产的价值在于与应用场景的紧密结合&#xff0c;不同场景下数据所贡献的经济价值存在显著差异。例如&…

WIFI 模组8286驱动

原理图&#xff1a; 注&#xff1a;使用的数串口1的引脚&#xff0c;PA1是发送端引脚&#xff0c;PA3是接收端引脚&#xff0c;PA7串口的使能位。 1.0 WIFI模组驱动 驱动初始化函数&#xff1a; void WifiModuleDrvInit(void) {WifiGpioInit();WifiUartInit(115200);WifiDmaIn…

window系统如何适用redis

目录 1、解压缩安装包 2、命令行启动服务 3、客户端连接 4、redis客户端工具 1、解压缩安装包 2、命令行启动服务 3、客户端连接 4、redis客户端工具

CSS3多行多栏布局

当前布局由6个等宽行组成&#xff0c;其中第四行有三栏&#xff0c;第五行有四栏。 重点第四行设置&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>img {hei…

踩坑集之Video Processing Subsystem

问题描述 Video Processing Subsystem (VPSS) 功能强大&#xff0c;但我们在应用中只需要其中某个子功能。如果使用完整版本&#xff0c;资源消耗会非常大。VPSS将所有子功能封装在一起&#xff0c;所以我们将IP配置为仅包含CSC的模式&#xff0c;以为不需要的功能就不会影响系…