zoukankan      html  css  js  c++  java
  • 《深入浅出WPF》6.0 绑定

    数据是编程的核心

    6.1 DataBinding重要性

    程序三层结构:数据存储、数据处理、数据表示

    算法分布:数据库内部、读写数据、业务逻辑、数据展示、界面与逻辑的交互

    逻辑层优于展示层的功能支持:DataBinding、DependencyProperty、

    DataTemplate

    6.2 Binding的实现

    定义类:注意要实现接口INotifyPerportyChanged自动通知属性发生变化更新数据,this.PropertyChanged.Invoke调用

    public class Studet : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                if (PropertyChanged != null)
                        {
                            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
                        }
            }
        }
    }
    

    UI编写:

    <StackPanel>
        <TextBox x:Name="textbox1"/>
        <Button x:Name="Button1" Content="修改" Width="130" Click="Button1_Click"/>
    </StackPanel>
    

    绑定方式1:

    //实例化绑定类
    Binding binding = new Binding();
    binding.Source = studet;
    binding.Path = new PropertyPath("Name");
    //绑定
    BindingOperations.SetBinding(this.textbox1, TextBox.TextProperty, binding);
    

    绑定方式2:

    this.textbox1.SetBinding(TextBox.TextProperty, new Binding("Name") { Source = studet = new Studet()});
    

    6.3 绑定源与路径

    • Class对象
    • 自己或自己的容器、子集元素作为源
    • 另一个控件
    • 集合作为ItemsControl源
    • XML作为TreeView或Menu源
    • 多个控件关联到一个数据源
      绑定自己

    6.3.1控件作为数据源

    XAML中绑定

      <TextBox x:Name="textbox2" Text="{Binding ElementName=Slider1,Path=Value}" BorderBrush="Black"/>
            <Slider x:Name="Slider1"/>
    

    C# 中绑定

       this.textbox3.SetBinding(TextBox.TextProperty, new Binding("Value") { ElementName = "Slider2" });
    

    6.3.2 绑定的方向及数据更新

    绑定方向:Mode

    数据更新触发方式:UpdateSourceTrigger

      <TextBox x:Name="textbox1" Text="{Binding ElementName=Slider1,Path=Value,Mode=OneWayToSource,UpdateSourceTrigger=PropertyChanged}" />
    
    # 注意
    * NotifySourceUpdated设置为TREU会触发SourceUpdated事件
    * NofifyTargetUpdated设置为TRUE会触发TargetUpdated事件
    

    6.3.3 绑定的路径Path

    绑定支持多级路径

    <TextBox x:Name="textbox2" BorderBrush="Black"/>
    <TextBox Text="{Binding ElementName=textbox2,Path=Text.Length,Mode=OneWay}"/>
    
    <TextBox Text="{Binding ElementName=textbox2,Path=Text.[3],Mode=OneWay}"/>
    <TextBox Text="{Binding ElementName=textbox2,Path=Text[3],Mode=OneWay}"/>
    

    当使用集合元素作为绑定值时,把默认元素当作Path使用,使用斜杠/,可以使用多级斜杠

    List<string> StringList = new List<string>() { "Tim", "Tom", "Blog" };
    textbox3.SetBinding(TextBox.TextProperty, new Binding("/") { Source = StringList });
    textbox4.SetBinding(TextBox.TextProperty, new Binding("/[2]") { Source = StringList,Mode=BindingMode.OneWay });
    textbox5.SetBinding(TextBox.TextProperty, new Binding("/Length") { Source = StringList,Mode=BindingMode.OneWay });
    

    6.3.4 没有绑定路径的Path

    应用于直接取绑定对象本身的值,Path在XAML中可以不写或者写点号,但是在C#中需要写

    <StackPanel>
        <StackPanel.Resources>
            <sys:String x:Key="string1">AAAAA</sys:String>
        </StackPanel.Resources>
        <TextBox x:Name="textbox1" Text="{Binding Path=., Source={StaticResource ResourceKey=string1},Mode=OneWay}"/>
    </StackPanel>
    
    string string1 = "ABCDEF";
    textbox2.SetBinding(TextBox.TextProperty, new Binding(".") { Source = string1 });
    

    6.3.5 为绑定指定源

    绑定源:

    • CLR类型单个对象,如果要实现数据更新通知,要实现INotifyPropertyChanged接口,激发PropertyChanged事件,如Class
    • CLR类型集合,如数组、List
    • ADO.NET数据对象,如Datatable和DataView等
    • XMLDtatprovider提供的XML数据,可应用于TreeView等控件
    • 依赖对象(dependencyProperty)
    • 容器的DataContext
    • XAML通过Element指定
    • 通过Binding的RelativeSource指定
    • ObjectDataProvider
    • LINQ检索

    6.3.6 DataContext作为绑定源

    每一个WPF控件都拥有DataContext属性,UI元素树每一个节点都拥有该属性

    默认没有写绑定Source,那么会默认向根部寻找所有节点的DataContext属性的Path

    <StackPanel>
        <StackPanel.DataContext>
            <local:student Age="5" Name="tom" ID="34"/>
        </StackPanel.DataContext>
        <Grid>
            <StackPanel>
                <TextBox Text="{Binding Path=Age}"/>
                <TextBox Text="{Binding Path=Name}"/>
                <TextBox Text="{Binding Path=ID}"/>
            </StackPanel>
        </Grid>
    </StackPanel>
    
    # 注意,这个只能向根结点找数据,因为属性值沿着UI元素向下传递,如果内层未设置属性,则属性值会向下传递
    
    <StackPanel DataContext="ABD">
        <StackPanel>
            <Grid>
                <Grid>
                    <Grid >
                        <Button Height="50" x:Name="BTN1" Click="BTN1_Click"/>
                    </Grid>
                </Grid>
            </Grid>
        </StackPanel>  
    </StackPanel>
    
    private void BTN1_Click(object sender, RoutedEventArgs e)
    {
        BTN1.Content = BTN1.DataContext;
    }
    

    失败案例:

    <StackPanel>       
        <Grid>
            <StackPanel>
                <TextBox Text="{Binding Path=Age}"/>
                <TextBox Text="{Binding Path=Name}"/>
                <TextBox Text="{Binding Path=ID}"/>
                <StackPanel>
                    <StackPanel.DataContext>
                        <local:student Age="5" Name="tom" ID="34"/>
                    </StackPanel.DataContext>
                </StackPanel>
            </StackPanel>          
        </Grid>
    </StackPanel>
    

    6.3.7 Itemsource集合对象作为源

    ItemsSource属性:设置对象源

    DisplayMemberPath属性:设置显示的属性

    示例一:

    <StackPanel x:Name="stackPanel" Background="LightBlue">
        <TextBlock Text="studentID:" FontWeight="Bold" Margin="5"/>
        <TextBox x:Name="textBoxId" Margin="5"/>
        <TextBlock Text="Stdent List:" FontWeight="Black" Margin="5"/>
        <ListBox x:Name="ListBoxStudents" Height="110" Margin="5"/>
    </StackPanel>
    
    public Window6()
    {
    
        InitializeComponent();
        List<student> students = new List<student>()
        {
            new student(){Id=0,Name="Tom",Age=29},
            new student(){Id=1,Name="Tim",Age=28},
            new student(){Id=2,Name="Kyle",Age=27},
            new student(){Id=3,Name="Tony",Age=26},
            new student(){Id=4,Name="Vina",Age=25},
            new student(){Id=5,Name="Mike",Age=24},
        };
        this.ListBoxStudents.ItemsSource = students;
        this.ListBoxStudents.DisplayMemberPath = "Name";
    
        Binding binding = new Binding("SelectedItem.Id") { Source = this.ListBoxStudents };
        this.textBoxId.SetBinding(TextBox.TextProperty, binding);
    }
    public class student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
    
    # 注意其中
    * ItemsSource、DisplayMemberPath使用
    * SelectedItem.Id的使用
    

    示例二删除DisplayMemberPath属性后,通过模板方式在XAML中使用:

    <StackPanel x:Name="stackPanel" Background="LightBlue">
        <TextBlock Text="studentID:" FontWeight="Bold" Margin="5"/>
        <TextBox x:Name="textBoxId" Margin="5"/>
        <TextBlock Text="Stdent List:" FontWeight="Black" Margin="5"/>
        <ListBox x:Name="ListBoxStudents" Height="110" Margin="5">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Id}" Width="30"/>
                        <TextBlock Text="{Binding Path=Name}" Width="60"/>
                        <TextBlock Text="{Binding Path=Age}" Width="30"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
    
    # 注意
    * 一般建议用ObservableCollection替代List,因为继承了INotifyCollectionChanged和INotifyproperChanged
    

    6.3.8使用ADO.net作为源

    使用属性:ItemSource、DisplaymemberPath

    DataTable dataTable= this.Loadtb();
    this.Listbox1.DisplayMemberPath = "Name";
    this.Listbox1.ItemsSource = dataTable.DefaultView;
    

    使用ListView

    //this.Lisview1.ItemsSource = this.Loadtb().DefaultView;
    this.Lisview1.DataContext = this.Loadtb();
    this.Lisview1.SetBinding(ListView.ItemsSourceProperty, new Binding());
    
    <StackPanel>
        <ListView x:Name="Lisview1" Height="200" BorderBrush="Black">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Path=Id}" Width="60"/>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}" Width="60"/>
                    <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Path=Age}" Width="60"/>
                </GridView>
            </ListView.View>            
        </ListView>
    </StackPanel>
    

    6.3.9 使用XML作为绑定源

    <Window.Resources>
        <XmlDataProvider x:Key="xdp" XPath="Filesystem/Folder">
            <x:XData>
                <Filesystem xmlns="">
                    <Folder Name="Books">
                        <Folder Name="Programming">
                            <Folder Name="Windows">
                                <Folder Name="WPF"/>
                                <Folder Name="MFC"/>
                                <Folder Name="Delphi"/>
                            </Folder>
                        </Folder>
                        <Folder Name="Tools">
                            <Folder Name="Development"/>
                            <Folder Name="Designment"/>
                            <Folder Name="Players"/>
                        </Folder>
                    </Folder>    
                </Filesystem>                      
            </x:XData>            
        </XmlDataProvider>
    </Window.Resources>
    <Grid>
        <TreeView ItemsSource="{Binding Source={StaticResource xdp}}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding XPath=Folder}">
                    <CheckBox  Content="{Binding XPath=@Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
    

    * 6.3.10 使用LINQ语法检索结果

    * 6.3.11使用Objectdataprovider

    *6.3.12 RelativeSource UI相对位置控件作为绑定

    6.4 Binding数据转换与校验

    6.4.1 绑定的数据校验

  • 相关阅读:
    Lambda表达式、依赖倒置
    ASP.NET vNext 概述
    Uname
    RHEL4 i386下安装rdesktop【原创】
    Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
    How to decompile class file in Java and Eclipse
    先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)
    Google App Engine 学习和实践
    【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询
    js正則表達式语法
  • 原文地址:https://www.cnblogs.com/ycccq/p/13491182.html
Copyright © 2011-2022 走看看