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));
}
}
}
}
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()));
}
}
}
}
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(); }
}
}
}
<
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
>
?
之前一篇文章 對象數據綁定 里提到三個例子,第一個例子用了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.
?
?
?
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

