zoukankan      html  css  js  c++  java
  • 《深入浅出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;
  • 相关阅读:
    UVA12125 March of the Penguins (最大流+拆点)
    UVA 1317 Concert Hall Scheduling(最小费用最大流)
    UVA10249 The Grand Dinner(最大流)
    UVA1349 Optimal Bus Route Design(KM最佳完美匹配)
    UVA1212 Duopoly(最大流最小割)
    UVA1395 Slim Span(kruskal)
    UVA1045 The Great Wall Game(二分图最佳匹配)
    UVA12168 Cat vs. Dog( 二分图最大独立集)
    hdu3488Tour(KM最佳完美匹配)
    UVA1345 Jamie's Contact Groups(最大流+二分)
  • 原文地址:https://www.cnblogs.com/tt2015-sz/p/4800058.html
Copyright © 2011-2022 走看看