• 《深入浅出WPF》笔记二


    1、消息驱动与事件驱动

    事件 即封装过的消息

    2、数据驱动

    3、Binding

    Source、Target、Path、INotifyPropertyChanged结构

    this.textBoxName.SetBinding(TextBox.TextProperty,new Binding("Name){Source=stu=new Student()});

    4、把控件作为Binding的Source

    <Slider x:Name="slider1" Maximum="100" Minimun="0"/>
    <TextBox x:Name="textBox1" Text="{Binding Value,ElementName=slider1}"/>

    在C#中一般不必使用ElementName属性,直接将对象赋值给Binding的Source属性即可。 

    5、Binding的Mode(数据流向)

    TwoWay、OneWay、OnTime、OneWayToSource、Default

    6、Binding的UpdateSourceTrigger

    PropertyChanged、LostFocus、Explicit、Default

    7、Binding的其他属性:NotifyOnSourceUpdated和NotifyOnTargetUpdated,监听激发的事件可以找出有哪些数据或控件被更新了。

    8、Binding的Path

    <TextBox x:Name="textBox1"/>
    <TextBox x:Name="textBox2" Text="{Binding Path=Text.Length,ElementName=textBox1,Mode=OneWay}"/>
    <TextBox x:Name="textBox3" Text="{Binding Path=Text[3],ElementName=textBox1,Mode=OneWay}"/>

    当使用一个集合或DataView作为Binding源时,如果想把默认元素作为Path使用,则使用如下语法:

    1 List<string> stirngList=new List<string>(){"Tim","Tom","Blog"};
    2 this.textBox1.SetBinding(TextBox.TextProperty,new Binding("/"){Source=stringList});
    3 this.textBox2.SetBinding(TextBox.TextProperty,new Binding("/Length"){Source=stringList});
    4 this.textBox3.SetBinding(TextBox.TextProperty,new Binding("/[3]"){Source=stringList});

     如果集合元素的属性仍然是一个集合,想把子集中的元素作为Path,则可以使用多级斜线的语法(类似文件路径的那种,一级一级往下找)。

    9、当Binding的Source本身只是数据(string、int等)时,Binding的Path设置为“.”(XAML中可以省略该设置。)

    10、为Binding指定Source的几种方法

    (1)普通的CLR类型单个对象

    如果实现了INotifyPropertyChanged接口,则在set属性时激发PropertyChanged事件来通知Binding数据已更新。

    (2)普通CLR集合类型的对象(数组,List<T>,ObservableCollection<T>)

    一般把控件的ItemsSource属性使用Binding关联到一个集合对象上。

    (3)ADO.NET数据对象(DataTable和DataView等)

    <Grid>
        <ListView x:Name="listViewStudents">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>            
    1 DataTable dt=this.Load();
    2 this.listViewStudents.ItemsSource=dt.DefaultView;

    或者

    DataTable dt=this.Load();
    this.listViewStudents.DataContext=dt;
    this.listViewStudents.SetBinding(ListView.ItemsSourceProperty,new Binding());

    (4)XmlDataProvider把XML数据指定为Source

    可以把树状结构的XML数据作为Source指定给级联控件(TreeView和Menu)的Binding。

    使用XML数据作为Binding的Source时,我们使用XPath属性来指定数据的来源,而不是Path属性。

    <Window.Resources>
        <XmlDataProvider x:Key="xdp" XPath="FileSystem/Folder">
            <x:Data>
                <FileSystem xmlns="">
                    <Folder Name="Books">
                        <Folder Name="Cooks">
                            <Folder Name="Cook1"/>
                            <Folder Name="Cook2"/>
                        </Folder>
                        <Folder Name="Tools">
                            <Folder Name="Tool1"/>
                            <Folder Name="Tool2"/>
                        </Folder>
                    </Folder>
                </FileSystem>
            </x:Data>
        </XmlDataProvider>
    </Window.Resources>    
    <Grid>
        <TreeView ItemsSource="{Binding Source={StaticResouce xdp}}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding XPath=Folder}">
                    <TextBlock Text="{Binding XPath=@Name}"/>
                </HierarchicalDataTemplate >
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>

     (5)依赖对象(Dependency Object)

    (6)把容器的DataContext指定为Source

    建立一个Binding,只设置Path而不设置Source,该Binding就会沿着控件树一层层往外找,直到找到带有Path指定属性的对象。如果到了控件树根部仍然找不到,那么该Binding就得不到数据。

    <StackPanel>
        <StackPanel.DataContext>
            <local:Student Id="1" Age="29" Name="Tim"/>
        </StackPanel.DataContext>
        <Grid>
            <StackPanel>
                <TextBox Text="{Binding Path=Id}"/>
                <TextBox Text="{Binding Path=Name}"/>
                <TextBox Text="{Binding Path=Age}"/>
            </StackPanel>
        </Grid>
    </StackPanel>

    实际上,DataContext是一个依赖属性,当没有为当前控件的依赖属性显式赋值时,控件就会把自己容器的属性值当做自己的属性值。也就是属性值沿着元素树向下传递了。

    当多个控件Binding关注同一个对象时,可以使用DataContext。

    将A窗体中的控件或控件的值作为窗体A的DataContext,可以将该控件暴露给其他的窗体。

    (7)通过ElementName属性指定Source

    (8)RelativeSource

    <TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid},AncestorLevel=1},Path=Name}"

    (9)ObjectDataProvider

    用于数据源的数据不是通过属性而是通过方法暴露给外界的时候。

     1 ObjectDataProvider odp=new ObjectDataProvider();
     2 odp.ObjectInstance=new Calculator();
     3 odp.MethodName="Add";
     4 odp.MethodParameters.Add("0");
     5 odp.MethodParameters.Add("0");
     6 
     7 Binding bindingToArg1=new Binding("MethodParameters[0]")
     8 {
     9    Source=odp;
    10    BindsDirectlyToSource=true;
    11    UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged  
    12 };
    13 
    14 Binding bindingToArg2=new Binding("MethodParameters[1]")
    15 {
    16    Source=odp;
    17    BindsDirectlyToSource=true;
    18    UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged  
    19 };
    20 
    21 Binding bindingToResult=new Binding(".")
    22 {
    23    Source=odp;
    24 };
    25 
    26 this.textBoxArg1.SetBinding(TextBox.TextProperty,bindingToArg1);
    27 this.textBoxArg2.SetBinding(TextBox.TextProperty,bindingToArg2);
    28 this.textBoxResult.SetBinding(TextBox.TextProperty,bindingToResult);

    (10)LINQ检索得到的数据对象作为数据源

    从一个填充好的List<Student>对象中检索出所有名字以T开头的学生。

    this.listViewStudents.ItemsSource=from stu in stilts where su.Name.StartsWith("T") select stu;

    如果数据存放在一个填充好的DataTable对象里:

     1 DataTable dt=this.GetDataTable();
     2 this.listViewStudents.ItemsSource=
     3     from row in dt.Rows.Cast<DataRow>()
     4     where Convert.ToString(row["Name"]).StartsWith("T")
     5     select new Student()
     6     {
     7         Id=int.Parse(row["Id"].ToString()),
     8         Name=row["Name"].ToString(),
     9         Age=int.Parse(row["Age"].ToString())
    10     };

     如果数据放在XML文件里:

     1 XDocument xdoc=XDocument.Load(@"D:RawData.xml");
     2 this.listViewStudents.ItemsSource=
     3     from element in xdoc.Descendants("Student")
     4     where element.Attribute("Name").Value.StartsWith("T")
     5     select new Student()
     6     {
     7         Id=int.Parse(element.Attribute("Id").Value);
     8         Name=element.Attribute("Name").Value;
     9         Age=int.Parse(element.Attribute("Age").Value);
    10     };

     11、Binding数据验证——ValidationRules

    Binding默认认为来自Source的数据总是正确地,若要校验来自Source的数据,需将校验条件的ValidatesOnTargetUpdated属性设置为true。

    12、Binding的数据转换——IValueConverter接口

    13、多路Binding

    用于UI需要显示的信息由不止一个数据来源决定的时候。

    比如,新用户注册的时候,用户名输入一致,邮箱输入一致时,注册按钮才可用。

    1 MutiBinding mb=new MultiBinding(){Mode=BindingMode.OneWay};
    2 mb.Bindings.Add(new Binding("Text"){Source=this.textBox1});
    3 mb.Bindings.Add(new Binding("Text"){Source=this.textBox2});
    4 mb.Bindings.Add(new Binding("Text"){Source=this.textBox3});
    5 mb.Bindings.Add(new Binding("Text"){Source=this.textBox4});
    6 mb.Converter=new LoginMultiBindingConverter();
    7 
    8 this.button1.SetBinding(Button.IsEnabledProperty,mb);

    Convert()方法的具体实现:

    1 if(!Value.Cast<string>().Any(text=>string.IsNullOrEmpty(text))
    2     && values[0].ToString()==values[1].ToString()
    3     && values[1].ToString()==values[3].ToString())
    4 {
    5     return true;
    6 }
    7 else
    8     return false;
  • 相关阅读:
    关于Js异常
    gitea windows 安装
    spring boot 错误页面配置
    mysql 常用用函数
    nginx 安装 tomcat pfx 格式证书
    git pull 报错
    maven 打 jar 包,包含 xml, 包含 额外 jar
    git clone 分支代码
    git 切换远程分支
    mycat 在 mysql 8.0 下 无法连接 bug
  • 原文地址:https://www.cnblogs.com/tt2015-sz/p/4800058.html
Copyright © 2020-2023  润新知