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 绑定的数据校验

  • 相关阅读:
    消息队列简介
    docker快速构建oracle数据库
    MySQL读写分离之amoeba
    Python替换文件内容
    Nginx图片及样式文件不记录访问日志
    shell方式切割tomcat日志
    split命令
    orange安装文档
    openresty安装文档
    MySQL中kill所有慢查询进程和锁表进程
  • 原文地址:https://www.cnblogs.com/ycccq/p/13491182.html
Copyright © 2011-2022 走看看