Binding的Source从何而来?

系统 1505 0

I. Binding to Object

1. Binding data using ObjectDataProvider

AC:Let’s say there is a CLR based data bound object that you are trying to implement. For example a collection of Tool objects, e.g.

  • An Object called Tool that contains a bunch of properties that we want to bind (in this case it just contains a description)
  • A Collection of Tool objects( ToolsCollection ); for example to populate a list box etc
  • A Factory to get the reference of  ToolsCollection objects which have collection<Tools>
        
          using
        
        
           System;


        
        
          using
        
        
           System.Collections.Generic;


        
        
          using
        
        
           System.Collections.ObjectModel;


        
        
          using
        
        
           System.ComponentModel;


        
        
          using
        
        
           System.Linq;


        
        
          using
        
        
           System.Text;


        
        
          using
        
        
           System.Threading.Tasks;




        
        
          namespace
        
        
           CLRDataBinding

{

    
        
        
          public
        
        
          class
        
        
           Tool : INotifyPropertyChanged

    {

        
        
        
          private
        
        
          string
        
         _description = 
        
          ""
        
        
          ;

        
        
        
          public
        
        
          string
        
        
           Description

        {

            
        
        
          get
        
        
          

            {

                
        
        
          return
        
        
           _description;

            }

            
        
        
          set
        
        
          

            {

                
        
        
          if
        
         (_description !=
        
           value)

                {

                    _description 
        
        =
        
           value;

                    NotifyPropertyChanged(
        
        
          "
        
        
          Description
        
        
          "
        
        
          );

                }

            }

        }

        
        
        
          public
        
         Tool(
        
          string
        
        
           description)

        {

            _description 
        
        =
        
           description;

        }



        
        
        
          public
        
        
          event
        
        
           PropertyChangedEventHandler PropertyChanged;

        
        
        
          protected
        
        
          void
        
         NotifyPropertyChanged(
        
          string
        
        
           propName)

        {

            
        
        
          if
        
         (PropertyChanged != 
        
          null
        
        
          )

            {

                PropertyChanged(
        
        
          this
        
        , 
        
          new
        
        
           PropertyChangedEventArgs(propName));

            }

        }



    }

}
        
      
View Code
        
          using
        
        
           System;


        
        
          using
        
        
           System.Collections.Generic;


        
        
          using
        
        
           System.Linq;


        
        
          using
        
        
           System.Text;


        
        
          using
        
        
           System.Threading.Tasks;


        
        
          using
        
        
           System.Collections.ObjectModel;




        
        
          namespace
        
        
           CLRDataBinding

{

    
        
        
          public
        
        
          class
        
         ToolsCollection : ObservableCollection<Tool>
        
          

    {

        
        
        
          public
        
        
           ToolsCollection()

        {

            CreateToolsData();

        }



        
        
        
          private
        
        
          void
        
        
           CreateToolsData()

        {

            
        
        
          for
        
         (
        
          int
        
         loop = 
        
          0
        
        ; loop < 
        
          1000
        
        ; loop++
        
          )

            {

                
        
        
          this
        
        .Add(
        
          new
        
         Tool(
        
          "
        
        
          Tool 
        
        
          "
        
         +
        
           loop.ToString()));

            }

        }

    }

}
        
      
View Code
        
          using
        
        
           System;


        
        
          using
        
        
           System.Collections.Generic;


        
        
          using
        
        
           System.Linq;


        
        
          using
        
        
           System.Text;


        
        
          using
        
        
           System.Threading.Tasks;




        
        
          namespace
        
        
           CLRDataBinding

{

    
        
        
          public
        
        
          class
        
        
           Factory

    {

        
        
        
          public
        
        
           ToolsCollection MyToolsCollection

        {

            
        
        
          get
        
         { 
        
          return
        
        
          new
        
        
           ToolsCollection(); }

        }

    }

}
        
      
View Code
        
          <
        
        
          Window 
        
        
          x:Class
        
        
          ="CLRDataBinding.MainWindow"
        
        
          

        xmlns
        
        
          ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        
        
          

        xmlns:x
        
        
          ="http://schemas.microsoft.com/winfx/2006/xaml"
        
        
          

        xmlns:clr
        
        
          ="clr-namespace:CLRDataBinding"
        
        
          

        Title
        
        
          ="MainWindow"
        
        
          

        Width
        
        
          ="525"
        
        
          

        Height
        
        
          ="350"
        
        
          >
        
        
          <
        
        
          Window.Resources
        
        
          >
        
        
          <
        
        
          ObjectDataProvider 
        
        
          x:Key
        
        
          ="FactoryDP"
        
        
           ObjectType
        
        
          ="
        
        
          {x:Type clr:Factory}
        
        
          "
        
        
          />
        
        
          <
        
        
          DataTemplate 
        
        
          x:Key
        
        
          ="ToolItemTemplate"
        
        
          >
        
        
          <
        
        
          StackPanel
        
        
          >
        
        
          <
        
        
          TextBlock 
        
        
          Text
        
        
          ="
        
        
          {Binding Description}
        
        
          "
        
        
          />
        
        
          </
        
        
          StackPanel
        
        
          >
        
        
          </
        
        
          DataTemplate
        
        
          >
        
        
          </
        
        
          Window.Resources
        
        
          >
        
        
          <
        
        
          Grid
        
        
          >
        
        
          <
        
        
          ListBox 
        
        
          ItemTemplate
        
        
          ="
        
        
          {StaticResource ToolItemTemplate}
        
        
          "
        
        
           ItemsSource
        
        
          ="
        
        
          {Binding Path=MyToolsCollection, Source={StaticResource FactoryDP}}
        
        
          "
        
        
          />
        
        
          </
        
        
          Grid
        
        
          >
        
        
          </
        
        
          Window
        
        
          >
        
      
View Code

 

之前一篇文章 对象数据绑定 里提到三个例子,第一个例子用了ObjectDataProvider没有用DataContext,第二个例子用了DataContext没有用 ObjectDataProvider,第三个例子既用了ObjectDataProvider也用了DataContext,但没有提到它们的区别,正 好在Beatriz Costa的blog上看到一篇好文章解释了为 什么需要 ObjectDataProvider 的问题。

ObjectDataProvider能实现四个特殊功能:

1. 传递参数到构造函数中

使用下面的XAML语句定义一个ObjectDataProvider,它会自动调用MySource类的默认构造函数初始化类
<ObjectDataProvider ObjectType="{x:Type local:MySource}" x:Key="odp1"/>
如果MySource类的构造函数允许传入参数的话,就可以这样定义ObjectDataProvider:
<ObjectDataProvider ObjectType="{x:Type local:MySource}" x:Key="odp1">
  <ObjectDataProvider.ConstructorParameters>
    <system:String>Jupiter</system:String>
  </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

2. 绑定到方法

ObjectDataProvider 除了 ObjectType的属性外还有MethodName的属性,MethodName属性将ObjectDataProvider绑定到方法,相当于是对数据源的包装,另外也可以定义方法的传入参数:
<ObjectDataProvider ObjectInstance="{StaticResource odp1}" MethodName="WeightOnPlanet" x:Key="odp2">
  <ObjectDataProvider.MethodParameters>
    <system:Double>95</system:Double>
  </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

3. 替换数据对象

和使用自己在resource中定义对象不同,ObjectDataProvider可以使里很简单的更换绑定的数据对象,只需要更换一下绑定的数据对象的名字。而使用自己在resource中定义对象,即使定义了相同的x:Key也不能达到自动更新的目的。
另,这里使用DataContext也能达到与ObjectDataProvider同样的效果。

4. 建立异步的数据对象

ObjectDataProvider有IsAsynchronous 可以将数据对象定义为异步的。
默认情况下ObjectDataProvider是同步的,XmlDataProvider是异步。

2. Binding DataContext in Window.DataContext (ObjectDataProvider not needed)

AuctionItem.cs: define Class AuctionItem : INotifyPropertyChanged
MyApp.xaml.cs: define Class AuctionItems : ObservableCollection<AuctionItem>
Window1.xaml.cs: use [CollectionViewSource cv = root.DataContext as CollectionViewSource;] to action in button event handler

Binding Process:

1)Define DataContext in Window1.xaml:  

      
        <
      
      
        Window.DataContext
      
      
        >
      
      
        <
      
      
        CollectionViewSource
      
      
        >
      
      
        <
      
      
        CollectionViewSource.Source
      
      
        >
      
      
        <
      
      
        local:AuctionItems
      
      
        />
      
      
        </
      
      
        CollectionViewSource.Source
      
      
        >
      
      
        </
      
      
        CollectionViewSource
      
      
        >
      
      
        </
      
      
        Window.DataContext
      
      
        >
      
    

2) Binding Listbox:

      
        <
      
      
        ListBox 
      
      
        ItemsSource
      
      
        ="
      
      
        {Binding Path=.}
      
      
        "
      
      
         IsSynchronizedWithCurrentItem
      
      
        ="True"
      
      
        >
      
    

3) Binding label: (the current item in listbox)

      
        <
      
      
        Label 
      
      
        Content
      
      
        ="
      
      
        {Binding Path=/}
      
      
        "
      
      
        >
      
    

4) DataTemplate

      
        <
      
      
        DataTemplate 
      
      
        DataType
      
      
        ="
      
      
        {x:Type local:AuctionItem}
      
      
        "
      
      
        >
      
      
        

...


      
      
        <
      
      
        Image
      
      
        >
      
      
        <
      
      
        Image.Source
      
      
        >
      
      
        <
      
      
        Binding 
      
      
        Path
      
      
        ="Image"
      
      
        />
      
      
        </
      
      
        Image.Source
      
      
        >
      
      
        </
      
      
        Image
      
      
        >
      
      
        

...
      
    

More: this sample also shows how to use Converter and MultiBinding

3. Binding DataContext in controls to Global ObjectDataProvider

sample:

MyApp.xaml:

      
        <
      
      
        Application.Resources
      
      
        >
      
      
        

 ...

 
      
      
        <
      
      
        ObjectDataProvider 
      
      
        x:Key
      
      
        ="Employees"
      
      
         ObjectType
      
      
        ="
      
      
        {x:Type local:MSEmployeeCollection}
      
      
        "
      
      
        />
      
      
        </
      
      
        Application.Resources
      
      
        >
      
    

Window1.xaml:

      
        <
      
      
        StackPanel 
      
      
        Margin
      
      
        ="10"
      
      
         DataContext
      
      
        ="
      
      
        {StaticResource Employees}
      
      
        "
      
      
        >
      
      
        

    ...

    
      
      
        <
      
      
        Button 
      
      
        Content
      
      
        ="
      
      
        {Binding Path=[0]}
      
      
        "
      
      
        />
      
      
        <
      
      
        ComboBox 
      
      
        ItemsSource
      
      
        ="
      
      
        {Binding}
      
      
        "
      
      
         SelectedIndex
      
      
        ="0"
      
      
        />
      
      
        </
      
      
        StackPanel
      
      
        >
      
    

1) DataContext another format : binding to StackPanel
2) Button bind to single item [0]
3) ComblBox bind to multi items, so no Path

II. Binding to XML

1. Use Source include .xml file to XmlDataProvider

      
        <?
      
      
        xml version='1.0' encoding='utf-8'
      
      
        ?>
      
      
        <
      
      
        StackPanel 
      
      
        xmlns
      
      
        ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
      
         xmlns:x
      
      
        ="http://schemas.microsoft.com/winfx/2006/xaml"
      
      
         Margin
      
      
        ="10"
      
      
        >
      
      
        <
      
      
        StackPanel.Resources
      
      
        >
      
      
        <
      
      
        XmlDataProvider 
      
      
        x:Key
      
      
        ="Blog"
      
      
         Source
      
      
        ="http://home.wangjianshuo.com/index.xml"
      
      
        />
      
      
        <
      
      
        DataTemplate 
      
      
        x:Key
      
      
        ="TitleTemplate"
      
      
        >
      
      
        <
      
      
        TextBlock 
      
      
        Text
      
      
        ="
      
      
        {Binding XPath=title}
      
      
        "
      
      
        />
      
      
        </
      
      
        DataTemplate
      
      
        >
      
      
        </
      
      
        StackPanel.Resources
      
      
        >
      
      
        <
      
      
        Label 
      
      
        Content
      
      
        ="
      
      
        {Binding Source={StaticResource Blog}, XPath=/rss/channel/title}
      
      
        "
      
      
         FontSize
      
      
        ="24"
      
      
         FontWeight
      
      
        ="Bold"
      
      
        />
      
      
        <
      
      
        Label 
      
      
        Content
      
      
        ="
      
      
        {Binding Source={StaticResource Blog}, XPath=/rss/channel/description}
      
      
        "
      
      
         FontSize
      
      
        ="18"
      
      
        />
      
      
        <
      
      
        DockPanel 
      
      
        DataContext
      
      
        ="
      
      
        {Binding Source={StaticResource Blog}, XPath=/rss/channel/item}
      
      
        "
      
      
        >
      
      
        <
      
      
        ListBox 
      
      
        DockPanel.Dock
      
      
        ="Left"
      
      
         ItemsSource
      
      
        ="
      
      
        {Binding}
      
      
        "
      
      
         ItemTemplate
      
      
        ="
      
      
        {StaticResource TitleTemplate}
      
      
        "
      
      
         IsSynchronizedWithCurrentItem
      
      
        ="True"
      
      
        />
      
      
        <
      
      
        TextBox 
      
      
        Name
      
      
        ="Contents"
      
      
         Text
      
      
        ="
      
      
        {Binding XPath=description}
      
      
        "
      
      
         TextWrapping
      
      
        ="Wrap"
      
      
         Width
      
      
        ="Auto"
      
      
        />
      
      
        </
      
      
        DockPanel
      
      
        >
      
      
        </
      
      
        StackPanel
      
      
        >
      
    

2. Use x:XData define the xml structure inside current XmlDataProvider

      
        <
      
      
        StackPanel 
      
      
        xmlns
      
      
        ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
      
        

            xmlns:x
      
      
        ="http://schemas.microsoft.com/winfx/2006/xaml"
      
      
        >
      
      
        <
      
      
        StackPanel.Resources
      
      
        >
      
      
        <
      
      
        XmlDataProvider 
      
      
        x:Key
      
      
        ="FavoriteColors"
      
      
        >
      
      
        <
      
      
        x:XData
      
      
        >
      
      
        <
      
      
        Colors 
      
      
        xmlns
      
      
        =""
      
      
        >
      
      
        <
      
      
        Color
      
      
        >
      
      Blue
      
        </
      
      
        Color
      
      
        >
      
      
        <
      
      
        Color
      
      
        >
      
      Black
      
        </
      
      
        Color
      
      
        >
      
      
        <
      
      
        Color
      
      
        >
      
      Green
      
        </
      
      
        Color
      
      
        >
      
      
        <
      
      
        Color
      
      
        >
      
      Red
      
        </
      
      
        Color
      
      
        >
      
      
        </
      
      
        Colors
      
      
        >
      
      
        </
      
      
        x:XData
      
      
        >
      
      
        </
      
      
        XmlDataProvider
      
      
        >
      
      
        </
      
      
        StackPanel.Resources
      
      
        >
      
      
        <
      
      
        TextBlock 
      
      
        HorizontalAlignment
      
      
        ="Center"
      
      
        

             FontWeight
      
      
        ="Bold"
      
      
        >
      
      
        

    XML Example

  
      
      
        </
      
      
        TextBlock
      
      
        >
      
      
        <
      
      
        ListBox 
      
      
        Width
      
      
        ="200"
      
      
         Height
      
      
        ="300"
      
      
        

           ItemsSource
      
      
        ="
      
      
        {Binding Source={StaticResource FavoriteColors},

           XPath=/Colors/Color}
      
      
        "
      
      
        >
      
      
        </
      
      
        ListBox
      
      
        >
      
      
        </
      
      
        StackPanel
      
      
        >
      
    

III. Binding to Control

1:

      
        <
      
      
        Window 
      
      
        xmlns
      
      
        ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
      
        >
      
      
        <
      
      
        Canvas
      
      
        >
      
      
        <
      
      
        TextBox 
      
      
        Name
      
      
        ="theTextBox"
      
      
         Text
      
      
        ="Hello"
      
      
        />
      
      
        <
      
      
        TextBlock 
      
      
        Canvas.Top
      
      
        ="25"
      
      
        >
      
      
        <
      
      
        TextBlock.Text
      
      
        >
      
      
        <
      
      
        Binding 
      
      
        ElementName
      
      
        ="theTextBox"
      
      
         Path
      
      
        ="Text"
      
      
        />
      
      
        </
      
      
        TextBlock.Text
      
      
        >
      
      
        </
      
      
        TextBlock
      
      
        >
      
      
        </
      
      
        Canvas
      
      
        >
      
      
        </
      
      
        Window
      
      
        >
      
    

2:

      
        <
      
      
        Window 
      
      
        xmlns
      
      
        ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
      
        >
      
      
        <
      
      
        Canvas
      
      
        >
      
      
        <
      
      
        TextBox 
      
      
        Name
      
      
        ="theTextBox"
      
      
         Text
      
      
        ="Hello"
      
      
        />
      
      
        <
      
      
        TextBlock 
      
      
        Canvas.Top
      
      
        ="25"
      
      
        

               Text
      
      
        ="
      
      
        {Binding ElementName=theTextBox, Path=Text}
      
      
        "
      
      
        />
      
      
        </
      
      
        Canvas
      
      
        >
      
      
        </
      
      
        Window
      
      
        >
      
    

IX. Binding to ADO.NET

Similar to binding to object, create a dataset and return ds to DataContext.

 

 

 

 

 

Binding的Source从何而来?


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论