デザイン時におけるサンプルデータの表示 その1
下記のコードのように、XmlDataProviderを使ってXMLファイルからデータを取得、表示しているような場合には、デザイン時にデータの表示を含めたかたちで確認することができます。
XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Window1"
x:Name="Window"
Title="Window1"
Height="300" Width="300">
<Window.Resources>
<XmlDataProvider x:Key="PrefecturesDS" d:IsDataSource="True" Source="tohoku.xml"/>
<DataTemplate x:Key="Prefectureテンプレート">
<StackPanel>
<TextBlock Text="{Binding Mode=OneWay, XPath=Name}"/>
<TextBlock Text="{Binding Mode=OneWay, XPath=ID}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ListBox IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Mode=Default, Source={StaticResource PrefecturesDS}, XPath=/Prefectures/Prefecture}"
Margin="10" ItemTemplate="{DynamicResource Prefectureテンプレート}"/>
</Grid>
</Window>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Window1"
x:Name="Window"
Title="Window1"
Height="300" Width="300">
<Window.Resources>
<XmlDataProvider x:Key="PrefecturesDS" d:IsDataSource="True" Source="tohoku.xml"/>
<DataTemplate x:Key="Prefectureテンプレート">
<StackPanel>
<TextBlock Text="{Binding Mode=OneWay, XPath=Name}"/>
<TextBlock Text="{Binding Mode=OneWay, XPath=ID}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ListBox IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Mode=Default, Source={StaticResource PrefecturesDS}, XPath=/Prefectures/Prefecture}"
Margin="10" ItemTemplate="{DynamicResource Prefectureテンプレート}"/>
</Grid>
</Window>
これはExpression Blend(以下Blend)だけでなく、Visual Studio 2008(以下VS2008)のWPFデザイナ(”Cider”)でも同様です。
ところがこのようなケースはあまり多くなく、実際にはデータベースからデータを取得したり、あるいは実行時にデータが生成されることになるかと思います。そのような場合、当然ながら実行してみない限り表示されるデータは分かりません。
これまではデバッグ実行して画面のデザインを確認するという方法で特に問題はなかったと思いますが、画面のデザインを専門に担当する人がいるような場合にはそうもいきません。特にListBoxのようなItemsControlでは、ItemsPanelを変更して各データを自由にレイアウトできるため、データが表示されていないとデザインを確認できないという場合は多いと思われます。
そのような場合に、デザイン時にサンプルデータを表示させるということが必要になってくるかと思います。下記のページにいくつかそのための方法が書かれていましたので、ここではそのうちの1つを紹介します。
http://www.galasoft.ch/mydotnet/articles/article-2007091401.html
いきなりで申し訳ないですが、先にコードを見てもらった方が理解しやすいかと思いますのでまずコードを載せます。
Visual Basic(SampleData.vb)
Imports System.Collections.ObjectModel
Public Class SampleData
Inherits ObservableCollection(Of Item)
End Class
Public Class Item
Inherits DependencyObject
Public Sub New(ByVal myString As String, ByVal myInt As Integer)
Me.MyString = myString
Me.MyInt = myInt
End Sub
Public Property MyString() As String
Get
Return GetValue(MyStringProperty)
End Get
Set(ByVal value As String)
SetValue(MyStringProperty, value)
End Set
End Property
Public Shared ReadOnly MyStringProperty As DependencyProperty = _
DependencyProperty.Register("MyString", _
GetType(String), GetType(SampleData))
Public Property MyInt() As Integer
Get
Return GetValue(MyIntProperty)
End Get
Set(ByVal value As Integer)
SetValue(MyIntProperty, value)
End Set
End Property
Public Shared ReadOnly MyIntProperty As DependencyProperty = _
DependencyProperty.Register("MyInt", _
GetType(Integer), GetType(SampleData))
End Class
Public Class SampleData
Inherits ObservableCollection(Of Item)
End Class
Public Class Item
Inherits DependencyObject
Public Sub New(ByVal myString As String, ByVal myInt As Integer)
Me.MyString = myString
Me.MyInt = myInt
End Sub
Public Property MyString() As String
Get
Return GetValue(MyStringProperty)
End Get
Set(ByVal value As String)
SetValue(MyStringProperty, value)
End Set
End Property
Public Shared ReadOnly MyStringProperty As DependencyProperty = _
DependencyProperty.Register("MyString", _
GetType(String), GetType(SampleData))
Public Property MyInt() As Integer
Get
Return GetValue(MyIntProperty)
End Get
Set(ByVal value As Integer)
SetValue(MyIntProperty, value)
End Set
End Property
Public Shared ReadOnly MyIntProperty As DependencyProperty = _
DependencyProperty.Register("MyInt", _
GetType(Integer), GetType(SampleData))
End Class
ここではWPFおすすめのObservableCollectionにしていますが、ListとかBindingListあたりでも(サンプルデータの表示機能については)たぶん問題ありません。また、Itemオブジェクトでは依存関係プロパティにしていますが、これも普通のプロパティ(CLRプロパティ)でももちろんOKです。
XAML(Window1.xaml)
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:PreviewSampleData1="clr-namespace:PreviewSampleData1"
x:Class="Window1"
Title="Window1" Height="300" Width="300" Name="Window1">
<Window.Resources>
<ObjectDataProvider x:Key="SampleDataDS" d:IsDataSource="True"
ObjectType="{x:Type PreviewSampleData1:SampleData}"/>
<DataTemplate x:Key="SampleDataテンプレート">
<StackPanel>
<TextBlock Text="{Binding Path=MyInt}"/>
<TextBlock Text="{Binding Path=MyString}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox d:UseSampleData="True" Margin="10"
ItemTemplate="{DynamicResource SampleDataテンプレート}"
ItemsSource="{Binding Source={StaticResource SampleDataDS}}"
IsSynchronizedWithCurrentItem="True" Name="ListBox1" />
</Grid>
</Window>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:PreviewSampleData1="clr-namespace:PreviewSampleData1"
x:Class="Window1"
Title="Window1" Height="300" Width="300" Name="Window1">
<Window.Resources>
<ObjectDataProvider x:Key="SampleDataDS" d:IsDataSource="True"
ObjectType="{x:Type PreviewSampleData1:SampleData}"/>
<DataTemplate x:Key="SampleDataテンプレート">
<StackPanel>
<TextBlock Text="{Binding Path=MyInt}"/>
<TextBlock Text="{Binding Path=MyString}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox d:UseSampleData="True" Margin="10"
ItemTemplate="{DynamicResource SampleDataテンプレート}"
ItemsSource="{Binding Source={StaticResource SampleDataDS}}"
IsSynchronizedWithCurrentItem="True" Name="ListBox1" />
</Grid>
</Window>
Visual Basic(Window1.xaml.vb)
Imports System.Collections.ObjectModel
Class Window1
Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim realData As New SampleData()
realData.Add(New Item("青森", 1))
realData.Add(New Item("秋田", 2))
realData.Add(New Item("岩手", 3))
realData.Add(New Item("山形", 4))
realData.Add(New Item("宮城", 5))
realData.Add(New Item("福島", 6))
ListBox1.ItemsSource = realData
End Sub
End Class
Class Window1
Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
Dim realData As New SampleData()
realData.Add(New Item("青森", 1))
realData.Add(New Item("秋田", 2))
realData.Add(New Item("岩手", 3))
realData.Add(New Item("山形", 4))
realData.Add(New Item("宮城", 5))
realData.Add(New Item("福島", 6))
ListBox1.ItemsSource = realData
End Sub
End Class
オブジェクトを作り、それをObjectDataProviderを使ってデータソースとしているという一般的な手法かと思います。このように作成した場合、Window1.xamlはBlendのアートボード上で下記のように表示されます。
VS2008のWPFデザイナでは下記のように表示されます。
アプリケーションを実行すると下記のように表示されます。
ここでのポイントはWindow1.xamlの下記の部分です。
d:UseSampleData="True"
以前の投稿でご紹介したXAML Readerに無視されるmc:Ignorable属性が使われていますが、UseSampleDataがTureに設定されているとBlendがサンプルデータを生成して表示してくれます。これは[データ テンプレートの作成ダイアログ]の[サンプルデータの作成]チェックボックスをチェックすることで、このようなXAMLを自動的に生成してくれます。
なお、今のところ対応してるのはStringとInteger(Doubleなどは未確認)ぐらいのようで、DateTimeやColorなどのサンプルデータは表示されません。ちなみにStringのサンプルデータは「りんご」、「ナシ」、「オレンジ」、「バナナ」、「グレープフルーツ」の5種類がランダムで表示されるようです。
非常に長くなってしまいましたので、上記のページに書かれている他の方法については時間が取れればまたご紹介したいと思います。