LINQ to SQLクラスの作成とWPFでの表示

前回の投稿WPF編です。4番までWindowsフォーム編のときと手順が同じになるので、今回は5番から始めます。


5.Expression Blend(SP1の適用が必要)で、作成したプロジェクトを開き、[プロジェクト]パネルの下部にあるデータソースの一覧から[+CLRオブジェクト]と書いてあるボタンをクリックします。


6.CLRオブジェクトデータソースの追加]ダイアログで「WpfApplication1」という項目を展開して「Customers」を選択し、[OK]ボタンをクリックします。



7.[資産ライブラリ]から、ListBoxコントロールをデフォルトで配置されているレイアウト要素Gridの中に配置します(大きさや位置などは適宜調整)。このとき、ListBoxの名前(Nameプロパティ)をListBox1に設定しておきます。


8.データソースの一覧にある「Customers」を配置したListBoxコントロールへドラッグ&ドロップし、表示されたメニューから「Customersを"ListBox"にバインド」をクリックします。



9.[データバインドの作成]ダイアログでは、[フィールドの選択]にItemsSourceを選択し、[OK]ボタンをクリックします。


10.[データテンプレートの作成]ダイアログは、デフォルトのまま[OK]ボタンをクリックします。


11.Expression BlendVisual StudioのどちらかでWindowのLoadedイベントハンドラを作成し、下記のコードを記述します。

Class Window1
    Private DataClasses1DataContext1 As New DataClasses1DataContext
 
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        ListBox1.ItemsSource = DataClasses1DataContext1.Customers()
    End Sub
End Class


一応、ここまでの内容で下記のような表示となります。



なお、作成されたXAML側のObjectDataSourceは使っていません。DataTemplateを自動生成させたいがためにItemsSourceにバインドさせただけなので、ObjectDataSource部分とItemsSourceのバインド部分は削除しても問題ありません。


もう少し見た目を良くするには、ListBoxのItemsTemplateを修正します。ListBoxコントロールを右クリックしてコンテキストメニューから[他のテンプレートの編集]−[生成されたアイテムの編集(ItemsTemplate)]−[テンプレートの編集]を選択することで、ItemsTemplateの編集が可能です。



<DataTemplate x:Key="Customersテンプレート">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Path=Address}" Width="200"/>
        <Border Margin="10,0,10,0" Width="1" Background="Black"/>
        <TextBlock Text="{Binding Path=City}" Width="80"/>
        <Border Margin="10,0,10,0" Width="1" Background="Black"/>
        <TextBlock Text="{Binding Path=CompanyName}" Width="120"/>
        <Border Margin="10,0,10,0" Width="1" Background="Black"/>
        <TextBlock Text="{Binding Path=ContactName}" Width="80"/>
        <Border Margin="10,0,10,0" Width="1" Background="Black"/>
        <TextBlock Text="{Binding Path=ContactTitle}" Width="60"/>
        <Border Margin="10,0,10,0" Width="1" Background="Black"/>
        <TextBlock Text="{Binding Path=Country}" Width="60"/>
    </StackPanel>
</DataTemplate>


(項目数が多かったので少し減らしましたが)上記のようなDataTemplateを適用すると、下記のような表示になります。



このような表示であればListViewを使ってGridViewを用いたほうが良いですね。

LINQ to SQLクラスの作成とWindowsフォームでの表示

Visual Studio 2008のオブジェクトリレーショナルデザイナ(以下、O/Rデザイナ)を使って、エンティティクラスを作成する。」ここまではLINQのセッション等で行われているデモでよく見るのですが、取ってきたデータを表示するというのはコンソールだったりします。というわけで、ひとまずWindowsフォームに表示するにはどのような手順になるのかということをここに書いておきたいと思います。


MSDNライブラリでは、下記のページにその方法が書かれています。

LINQ to SQL クラスの作成 : O/R デザイナの使用



1.Windowsフォームアプリケーションを新規に作成(もちろんターゲットフレームワークは、3.5に設定)し、[プロジェクト]メニューの[新しい項目の追加]から[LINQ to SQLクラス]を追加します。



2.[サーバーエクスプローラ]を開き、そこにSQL Serverデータベース(ここではローカルのsqlexpressに作成したNorthwindデータベース)への接続を追加します。


3.追加したデータベースを展開し、テーブルの項目から任意のテーブル(ここではCustomers)を[O/Rデザイナ]上にドラッグ&ドロップします。



4.プロジェクトをビルドします。


5.[データ]メニューから[データソースウィンドウ]を開き、[新しいデータソースの追加…]をクリックします。その後、[アプリケーションのデータの取得元]として[オブジェクト]を選択します。


6.表示されているアセンブリ名(ここではWindowsApplication1)を展開し、バインド先のオブジェクトにCustomersを選択し、[完了]ボタンをクリックします。



7.[フォームデザイナ]を表示し、データソースウィンドウのCustomersの項目をフォーム上にドラッグ&ドロップします。


8.フォームのコードとして、下記のように記述します。

Public Class Form1
    Private DataClasses1DataContext1 As New DataClasses1DataContext
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        CustomersBindingSource.DataSource = DataClasses1DataContext1.Customers()
    End Sub
End Class




XAMLとXMLリテラルとLINQ

下記のblogにVisual Basic 9.0のXMLリテラルを使ったおもしろいコードが紹介されていましたので、それを紹介したいと思います。

simplegeek



Visual Basic 9.0では、下記のようにコード内に直接XMLを記述することができ、代入された変数は型推論によりXElementオブジェクトとなります。
Visual Basic

Dim contact1 = _
    <contact>
        <name>Patrick Hines</name>
        <phone type="home">206-555-0144</phone>
        <phone type="work">425-555-0145</phone>
    </contact>


XamlReader(System.Windows.Markup名前空間)のLoad メソッドを使うと、StreamやXmlReaderからXAMLをロードすることができます。これを使い、下記のようにコード内に記述したXAMLから実際の要素オブジェクトを生成することができます。
Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim XMLliterals = _
    <StackPanel xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
        <Button xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>ボタン</Button>
    </StackPanel>
    Me.Content = System.Windows.Markup.XamlReader.Load(XMLliterals.CreateReader())
End Sub


さらにXMLリテラルでは、ASP.NETの埋め込みコードブロックに似た記述方法によりオブジェクトを埋め込むことができます。
Visual Basic
Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim XAMLButton = _
    <Button xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>ボタン</Button>
    Dim XMLliterals = _
    <StackPanel xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
        <%= XAMLButton %>
    </StackPanel>
    Me.Content = System.Windows.Markup.XamlReader.Load(XMLliterals.CreateReader())
 End Sub


ということは、当然クエリ式も埋め込めることになり、下記のような記述もできるということになります。
Visual Basic
Private Sub Window1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim n As Integer() = {1, 2, 3, 4}
    Dim XMLliterals = _
    <StackPanel xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
        <%= _
            From i _
            In n Select _
            <Button xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>ボタン その<%= i %></Button> _
        %>
    </StackPanel>
    Me.Content = System.Windows.Markup.XamlReader.Load(XMLliterals.CreateReader())
End Sub

Visual Basic LINQ Hands On Labs for Orcas Beta 1

めずらしくコードはVBで書かれたLINQのハンズオン資料が公開されています。

Download Visual Basic LINQ Hands On Labs for Visual Studio 2008 from Official Microsoft Download Center



2つのdocファイルが提供されており、1つはコレクションとSQLXMLの3つについて簡単に説明してあるもの、もう1つはLINQ TO SQLについて詳しく解説してあるものとなっているようです。


この資料を参考にして、最もシンプルなLINQ TO SQLを使ったWPFアプリケーションの作成手順を書いてみたいと思います。


1.Orcas Beta 1で、新規にWPFアプリケーションを作成します。


2.「新しい項目の追加」で、プロジェクトにLinq to SQLファイルをNorthWind.dbmlという名前で追加します。


3.サーバーエクスプローラでローカルのsqlexpressに接続します(NorthWindを使うので、ない場合は作成しておきます)。


4.NorthWind.dbmlファイルを開いた状態にし、サーバーエクスプローラNorthWindデータベースからCustomerテーブルをドラッグ&ドロップします。


5.下記のようにWindow1.xamlを書きます。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Window1"
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
  <Grid>
 
    <ListView x:Name="CustomerList" ItemsSource="{Binding}">
      <ListView.View>
        <GridView>
          <GridViewColumn Header="CompanyName" DisplayMemberBinding="{Binding Path=CompanyName}"/>
          <GridViewColumn Header="ContactName" DisplayMemberBinding="{Binding Path=ContactName}"/>
          <GridViewColumn Header="Country" DisplayMemberBinding="{Binding Path=Country}"/>
        </GridView>
      </ListView.View>
    </ListView>
 
  </Grid>
</Window>


6.Window1.vbファイルを下記のように書きます。
Class Window1
 
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        ' Use a standard connection string
        Dim db As New NorthwindDataContext()
 
        CustomerList.DataContext = From cust In db.Customers _
                Where cust.Country = "USA" _
                                Select cust
 
    End Sub
End Class


今回は表示にListViewを使いましたので、実行結果は下記のような表示となります。