• Binding的Source从何而来?


    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.

  • 相关阅读:
    访问者模式:男人女人区别
    享元模式:开发多个网站实例
    中介者模式:联合国实例
    职责链模式:加薪实例
    命令模式:烤羊肉串实例
    桥接模式:手机软件实例
    单例模式
    组合模式:公司管理系统实例
    备忘录模式:游戏进度实例
    适配器模式:篮球翻译实例
  • 原文地址:https://www.cnblogs.com/shawnzxx/p/3330307.html
Copyright © 2020-2023  润新知