WPFAQS – is a series on WPF frequently asked questions (FAQS). Today we will talk about “ObjectDataProvider” and how does it can be used as a binding source for different controls.
“ObjectDataProvider” Class resides in the “System.Windows.Data” namespace and derived from “DataSourceProvider”, provides a wrapper around objects and provides an elegant way to create those objects and use as a binding data source in XAML. It provides the following properties for you to execute a query on your object and bind to the results. The most important thing that I liked about it for using it asynchronously by setting “IsAsynchronous” property to specify the object creation in a worker thread or in the active context. Also you can use “ConstructorParameters” property enabling to pass parameters if some objects creation requires them. Another important property is the “ MethodName” property to call a method of an object, and if the method requires parameters to be passed, use “MethodParameters” property. Here is the class diagram for it.
Show time! Lets consider the following “BrushesHelper” static class and we’ll bind the “GetBrushNames” method using “ObjectDataProvider” in the XAML a little later, here it goes:
Also consider this Enum, we’ll also bind it using “ObjectDataProvider” in the XAML.
Here is the XAML, showing the bindings of the above types, “BrushesHelper” & “GridTypes”
1: <Window x:Class="Shams.Wpf.LegoDraw.LegoDrawWin"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:sys="clr-namespace:System;assembly=mscorlib"
5: xmlns:local="clr-namespace:Shams.Wpf.LegoDraw.Controls"
6: xmlns:model="clr-namespace:Shams.Wpf.LegoDraw.Model"
7: xmlns:utils="clr-namespace:Shams.Wpf.LegoDraw.Utils"
8: Title="WPF | LegoDraw | by shams@geekscafe.NET"
9: Width="447" Height="206" WindowStartupLocation="CenterScreen"
10: >
11:
12: <Window.Resources>
13: <ObjectDataProvider x:Key="brushes"
14: ObjectType="{x:Type utils:BrushesHelper}"
15: MethodName="GetBrushNames"/>
16:
17: <ObjectDataProvider x:Key="gridTypes"
18: MethodName="GetValues"
19: ObjectType="{x:Type sys:Enum}">
20: <ObjectDataProvider.MethodParameters>
21: <x:Type TypeName="model:GridTypes" />
22: </ObjectDataProvider.MethodParameters>
23: </ObjectDataProvider>
24: </Window.Resources>
25:
26: <Grid x:Name="LayoutRoot">
27: <Grid.RowDefinitions>
28: <RowDefinition Height="22"/>
29: <RowDefinition Height="2"/>
30: <RowDefinition Height="22"/>
31: <RowDefinition Height="*"/>
32: </Grid.RowDefinitions>
33: <StackPanel Grid.Row="2" Orientation="Horizontal" Background="Silver">
34: <TextBlock Margin="5,0,5,0" VerticalAlignment="Center">Grid</TextBlock>
35: <ComboBox x:Name="ComboBoxGrid" Width="65"
36: ItemsSource="{Binding Source={StaticResource gridTypes}}"
37: SelectedValue="{Binding Source={StaticResource gridTypes}, Path=[1]}"
38: FontSize="11"
39: >
40: <ComboBox.ItemTemplate>
41: <DataTemplate>
42: <TextBlock Text="{Binding}" x:Name="PART_Text" />
43: <DataTemplate.Triggers>
44: <DataTrigger Binding="{Binding}" Value="Grid_8x8">
45: <Setter TargetName="PART_Text"
46: Property="Text" Value="8 x 8" />
47: </DataTrigger>
48: <DataTrigger Binding="{Binding}" Value="Grid_16x16">
49: <Setter TargetName="PART_Text"
50: Property="Text" Value="16 x 16" />
51: <Setter TargetName="PART_Text"
52: Property="FontWeight" Value="Bold" />
53: </DataTrigger>
54: <DataTrigger Binding="{Binding}" Value="Grid_24x24">
55: <Setter TargetName="PART_Text"
56: Property="Text" Value="24 x 24" />
57: </DataTrigger>
58: <DataTrigger Binding="{Binding}" Value="Grid_32x32">
59: <Setter TargetName="PART_Text"
60: Property="Text" Value="32 x 32" />
61: </DataTrigger>
62: <DataTrigger Binding="{Binding}" Value="Grid_36x36">
63: <Setter TargetName="PART_Text"
64: Property="Text" Value="36 x 36" />
65: </DataTrigger>
66: <DataTrigger Binding="{Binding}" Value="Grid_48x48">
67: <Setter TargetName="PART_Text"
68: Property="Text" Value="48 x 48" />
69: </DataTrigger>
70: <DataTrigger Binding="{Binding}" Value="Grid_64x64">
71: <Setter TargetName="PART_Text"
72: Property="Text" Value="64 x 64" />
73: </DataTrigger>
74: </DataTemplate.Triggers>
75: </DataTemplate>
76: </ComboBox.ItemTemplate>
77: </ComboBox>
78: <TextBlock Margin="5,0,5,0" VerticalAlignment="Center">Background</TextBlock>
79: <ComboBox x:Name="ComboBoxBackground"
80: ItemsSource="{Binding Source={StaticResource brushes}}"
81: Width="150"
82: SelectedValue="Transparent"
83: FontSize="11"
84: >
85: <ComboBox.ItemTemplate>
86: <DataTemplate>
87: <StackPanel Margin="1" Orientation="Horizontal" >
88: <Rectangle x:Name="PART_Rect" Fill="{Binding}"
89: Height="11" Width="11" Margin="1"/>
90: <TextBlock x:Name="PART_Text" Text="{Binding}"
91: Margin="3 0 0 0" />
92: </StackPanel>
93: </DataTemplate>
94: </ComboBox.ItemTemplate>
95: </ComboBox>
96: <TextBlock Margin="5,0,5,0" VerticalAlignment="Center">Delete mode</TextBlock>
97: <CheckBox x:Name="DeleteCheckBox" VerticalAlignment="Center"></CheckBox>
98:
99: </StackPanel>
100: <Grid Grid.Row="3" x:Name="MainGrid" Background="Gray">
101: <ScrollViewer Margin="0.5">
102: <Viewbox x:Name="chartViewBox" Stretch="UniformToFill">
103: <!--<local:LegoDrawBoard x:Name="MainBoard" Width="500" Height="500" Margin="1"/>-->
104: </Viewbox>
105: </ScrollViewer>
106: </Grid>
107: </Grid>
108: </Window>
Lines 13-23 creates the “ObjectDataProviders” using Enum “GridTypes” and “GetBrushNames” method of the type “BrushesHelper”. And they are set as binding data sources for the comboboxes in Lines 35 and 79 respectively. Here is the output for it.
That's all for now on “ObjectDataProvider” and look forward to your feed-back. enjoy :)