デザイン時におけるサンプルデータの表示 その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>





これは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


ここでは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>


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


オブジェクトを作り、それを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種類がランダムで表示されるようです。


非常に長くなってしまいましたので、上記のページに書かれている他の方法については時間が取れればまたご紹介したいと思います。