WPF数据绑定2

数据绑定

 

数据绑定连接源数据(Source)和目标数据(Target)

 

当数据变化的时候,通知绑定的目标,需要实现额外的接口。

比如INotifyPropertyChanged

BindingOperations.SetBinding()的三个参数,

第一个目标Traget,

第二个是目标属性,这是一个依赖属性。Static readonly dependencyProperty

第三个是Binding对象。(包含源Source,Path 源的属性,Convert 转换器)

 

 

 

 

 

数据源要求(Source):是一个对象,具有广阔的Property属性。

 

1.控件作为数据源

 

<StackPanel>

            <TextBox  x:Name=op Text="{Binding ElementName=s1, Path=Value}" ></TextBox>

            <Slider x:Name="s1" Maximum="100"></Slider>

        </StackPanel>

效果:

 

与之等效的c#语句:

BindingOperations.SetBinding(op, TextBox.TextProperty,new Binding() { Source =s1,Path =new PropertyPath("Value")  });

 

 

Mode属性:

绑定的模式:TwoWay,OneWay,OmnTime,OmneWayToSource,Default

默认绑定模式跟目标控件的编辑类型有关,如果目标控件是可编辑的,则Default是是双向模式,如果目标控件时只读的,则Default时单向的。

 

UpdateSourceTrigger属性:

更新触发模式,Default,PropertyChanged,LostFocus,Exlicit

这里默认时失去焦点才进行数据跟新的,可以设置触发模式为ProperChanged,则只要修改数量,就可以触发。

 

Path:

Path时绑定源数据,具有很多的形式。由于源数据本质上时一个树对象,所以需要注意取的时什么数据。

 

Student student = new Student();

            student.Name = "测试11";

            BindingOperations.SetBinding(op, TextBox.TextProperty,new Binding() { Source = student, Path = new PropertyPath("Name"),Mode = BindingMode.OneWay });

 

 

public class Student

    {

        public string Name { get; set; }

}

 

 

 

  List<Student> students = new List<Student>();

            students.Add(new Student() { Name = "测试1" });

            students.Add(new Student() { Name = "你好" });

            students.Add(new Student() { Name = "abcd" });

 

 

            BindingOperations.SetBinding(op1, TextBox.TextProperty,new Binding() { Source = students, Path = new PropertyPath("/"),Mode = BindingMode.OneWay });

            BindingOperations.SetBinding(op2, TextBox.TextProperty, new Binding() { Source = students, Path = new PropertyPath("/Name"), Mode = BindingMode.OneWay });

            BindingOperations.SetBinding(op3, TextBox.TextProperty, new Binding() { Source = students, Path = new PropertyPath("/Name.Length"), Mode = BindingMode.OneWay });

            BindingOperations.SetBinding(op4, TextBox.TextProperty, new Binding() { Source = students, Path = new PropertyPath("[1]"), Mode = BindingMode.OneWay });

            BindingOperations.SetBinding(op5, TextBox.TextProperty, new Binding() { Source = students, Path = new PropertyPath("[2].Name"), Mode = BindingMode.OneWay });

 

public class Student

    {

        public string Name { get; set; }

        public override string ToString()

        {

            return "Student:[" + Name+"]";

        }

}

 

<TextBox  x:Name="op1"    ></TextBox>

            <TextBox  x:Name="op2"    ></TextBox>

            <TextBox  x:Name="op3"    ></TextBox>

            <TextBox  x:Name="op4"    ></TextBox>

            <TextBox  x:Name="op5"    ></TextBox>

 

 

 

 

 

总结:使用属性名称,点(.),斜杠(/),方括号([1])表达属性。

其中点(.) 表示下级属性,斜杠表示集合的第一个元素,方括号([])表示取集合的第几个元素。

 

如果整个元数据就是要绑定的对象,则Path使用点(.) 表示,在xaml文法中甚至可以不写。

 

 

 

数据源的来源:

DataContext 每个WPF控件都具有整个属性。当不指定Source,仅仅指定Path的情况下,控件会沿着空间树向上寻找,查看每个节点的DataConetxt属性是否具有指定的Path.

 

 

<StackPanel.DataContext>

                <local:Student Name="王和诺" Age="32" Id="9001"></local:Student>

            </StackPanel.DataContext>

       

           

           

            <TextBox      Text="{Binding Path=Name}"></TextBox>

            <TextBox     Text="{Binding Path=Id}"></TextBox>

 

 

 

 

<StackPanel.DataContext>

                <sys:String>你好</sys:String>

            </StackPanel.DataContext>

       

          

            <TextBox     Text="{Binding .}"></TextBox>

 

 

1.当多个控件关联同一个对象时,可以使用DataContext

2.跨窗体传递数据时可以使用DataContext属性,因为控件可能时私有的,但是DataConetxt都是Public的。

 

 

<Window x:Class="WpfApp1.MainWindow"

        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:WpfApp1"

        xmlns:test="clr-namespace:System.Data;assembly=System.Data"

        xmlns:sys="clr-namespace:System;assembly=mscorlib"

        mc:Ignorable="d"

        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>

        <Binding ElementName="text1"/>

    </Window.DataContext>

    <Grid>

        <StackPanel>

            <TextBox x:Name="text1"></TextBox>

            <Button Click="text_Click" x:Name="text" Content="测试"></Button>

        </StackPanel>

 

    </Grid>

</Window>

 

 

private void text_Click(object sender, RoutedEventArgs e)

        {

            Window1 window1 = new Window1(this.DataContext);

            window1.ShowDialog();

        }

 

 

 

 

<TextBox Text="{Binding Path=Text}"></TextBox>

 

 

public Window1(object obj)

        {

            InitializeComponent();

            this.DataContext = obj;

        }

 

 

 

传递多行数据:

<StackPanel>

        <DataGrid x:Name="dg" AutoGenerateColumns="False" Height="100">

            <DataGrid.Columns>

                <DataGridTextColumn Header="名称1" Binding="{ Binding Name1}"></DataGridTextColumn>

                <DataGridTextColumn Header="名称2" Binding="{ Binding Name2}"></DataGridTextColumn>

                <DataGridTextColumn Header="名称3" Binding="{ Binding Name3}"></DataGridTextColumn>

            </DataGrid.Columns>

        </DataGrid>

 

        <Button Grid.Row="1"  Grid.Column="0" Content="测试" Click="text_Click"></Button>

        </StackPanel>

 

 

 

public MainWindow()

        {

            InitializeComponent();

 

            List<Student> students = new List<Student>();

 

            students.Add(new Student() { Name1 = "90", Name2 = "9003", Name3 = "测试为" });

 

            dg.ItemsSource = students;

 

 

 

 

        }

 

        private void text_Click(object sender, RoutedEventArgs e)

        {

 

            var obj = dg.SelectedItem;

            Window1 window1 = new Window1(obj);

            window1.ShowDialog();

 

 

public class Student

    {

        public string Name1 { get; set; }

        public string Name2 { get; set; }

        public string Name3{ get; set; }

 

        public override string ToString()

        {

            return "";

        }

}

 

public Window1(object obj)

        {

            InitializeComponent();

            this.DataContext = obj;

        }

 

<StackPanel>

           

      

        <TextBox Text="{Binding Path=Name1}"></TextBox>

        <TextBox Text="{Binding Path=Name2}"></TextBox>

        <TextBox Text="{Binding Path=Name3}"></TextBox>

        </StackPanel>

 

 

 

 

 

 

 

Datatable/dataview作为数据源。

 

相对数据源:RelativeSource

 

<StackPanel x:Name="text">

        <DataGrid x:Name="dg" AutoGenerateColumns="False" Height="100">

            <DataGrid.Columns>

                <DataGridTextColumn Header="名称1" Binding="{ Binding Name1}"></DataGridTextColumn>

                <DataGridTextColumn Header="名称2" Binding="{ Binding Name2}"></DataGridTextColumn>

                <DataGridTextColumn Header="名称3" Binding="{ Binding Name3}"></DataGridTextColumn>

            </DataGrid.Columns>

        </DataGrid>

 

            <Button Grid.Row="1"  Grid.Column="0" Height="40" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=StackPanel},Path=Name}" Click="text_Click"></Button>

        </StackPanel>

 

 

 

 

 

数据校验

 

 

Binding binding = new Binding();

            binding.Source = s1;

            binding.Path = new PropertyPath("Value");

            binding.ValidationRules.Add(new RangeValidationRule());

            binding.NotifyOnValidationError = true;

            BindingOperations.SetBinding(te, TextBox.TextProperty, binding);

 

            te.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(ValidationError));

 

 

 

 

void ValidationError(object sender, RoutedEventArgs e)

        {

            if (Validation.GetErrors(te).Count > 0)

            {

                MessageBox.Show("yc"+Validation.GetErrors(te)[0].ErrorContent.ToString());

            }

        }

 

 

 

<TextBox x:Name="te"></TextBox>

            <Slider Maximum="100" Margin="5" x:Name="s1"></Slider>

 

效果:

 

数据转换

 

实现IValueConvert 接口

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值