How is WPF Data Binding using Object Data Source in Visual Studio 2010 done?
- by Rob Perkins
This is probably mostly a question about how to use the VS 2010 IDE tools in a way the Microsofties didn't specifically intend. But since this is something I immediately tried without success.
I have defined a .NET 4.0 WPF Application project with a simple class that looks like this:
Public Class Class1
Public Property One As String = "OneString"
Public Property Two As String = "TwoString"
End Class
I then defined it as an "Object Data Source" in VS2010, using the IDE's "Add New Data Source..." feature. This exposes the class members in a GUI element in the IDE as given in this image:
Dragging "Class1" from that tool to the surface of "Window1.xaml" in a default "WPF Application" results in the design view looking like this:
And generated XAML like this:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="133" Width="170" xmlns:my="clr-namespace:WpfApplication1" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
>
<Window.Resources>
<CollectionViewSource x:Key="Class1ViewSource" d:DesignSource="{d:DesignInstance my:Class1, CreateList=True}" />
</Window.Resources>
<Grid DataContext="{StaticResource Class1ViewSource}" HorizontalAlignment="Left" Name="Grid1" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Content="One:" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" Margin="3" Name="OneTextBlock" Text="{Binding Path=One}" VerticalAlignment="Center" />
<Label Content="Two:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="3" Name="TwoTextBlock" Text="{Binding Path=Two}" VerticalAlignment="Center" />
</Grid>
Note the data bindings Text="{Binding Path=One}" and Text="{Binding Path=Two}" in the TextBlock elements.
Code-behind for Window1.xaml has this in Window_Loaded:
Class Window1
Private m_c1 As New Class1
Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim Class1ViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("Class1ViewSource"), System.Windows.Data.CollectionViewSource)
'Load data by setting the CollectionViewSource.Source property:
'Class1ViewSource.Source = [generic data source]
Me.DataContext = m_c1
End Sub
End Class
Running the application produces this output:
The expected result was that "OneString" would appear next to "One" and "TwoString" next to "Two" in the running window.
The question is: Why didn't this work? What will work instead? If I put bindings in a DataTemplate, it works. Blend, with its sample data stuff, implied that this should work, but it doesn't. I know I'm missing something pretty fundamental here; what is it?