ListViewを使ったDataGridもどきの作成-作成編-

作成したEditBoxコントロールを使い、編集機能を持つListViewコントロールを作成していきます。サンプル「ListViewEditable」では、ObjectDataProviderを使ってオブジェクトにバインドしていますが、ここではデータベースを使ってDataTableとバインドするものを作成します。


そのため、ローカルコンピュータのSQL Server Express EditionにNorthWindサンプルデータがインストールされた環境を前提としています。


今度はC#ではなく、Visual BasicWPFアプリケーションプロジェクトを新規に作成します。もちろんExpression Blend、Visual Sutido 2005のどちらでも構いません。


先ほど作成した「EditBox.dll」への参照を追加します。Expression Blendでプロジェクトを新規作成した場合には、System.Dataアセンブリへの参照が入っていませんので、こちらのアセンブリへの参照も追加します。


下記の内容を入力します。
Window1.xaml

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:Editing="clr-namespace:Editing;assembly=EditBox"
  x:Class="Window1"
  x:Name="Window"
  Title="Window1"
  Width="450" Height="380" Loaded="Window_Loaded">
 
  <Window.Resources>
 
  <Style TargetType="{x:Type Editing:EditBox}" >
      <Setter Property="HorizontalAlignment" Value="Left"  />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type Editing:EditBox}">
            <TextBlock x:Name="PART_TextBlockPart"
                Text="{Binding Path=Value,Mode=Twoway,RelativeSource =
                          {RelativeSource TemplatedParent}}"
                Width="{Binding Path=Width,Mode=Twoway,RelativeSource =
                          {RelativeSource TemplatedParent}}">
            </TextBlock>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
 
  </Window.Resources>
 
  <StackPanel x:Name="LayoutRoot">
    <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}"
      x:Name="ListView1" Width="Auto" Height="Auto">
      <ListView.View>
        <GridView>
          <GridViewColumn DisplayMemberBinding="{Binding Path=LastName}"
            Header="苗字" Width="100"/>
          <GridViewColumn DisplayMemberBinding="{Binding Path=FirstName}"
            Header="名前" Width="100"/>
          <GridViewColumn Header="役職" Width="200" x:Name="gvColumn3">
            <GridViewColumn.CellTemplate>
              <DataTemplate>
                <Editing:EditBox Value="{Binding Path=Title, Mode=TwoWay}"
                Height="25" Width="{Binding Path=Width, ElementName=gvColumn3}"/>
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>
    <Button HorizontalAlignment="Left" Margin="10"
      Width="75" Height="25" Content="更新" Click="Button_Click"/>
  </StackPanel>
</Window>


Window1.xaml.vb
Imports System
Imports System.IO
Imports System.Net
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Navigation
Imports System.Data
Imports System.Data.SqlClient
 
Partial Public Class Window1
    Public Sub New()
        MyBase.New()
 
        Me.InitializeComponent()
 
        ' オブジェクト作成に必要なコードをこの点の下に挿入します。
    End Sub
 
    Dim table As New DataTable()
    Dim dataAdapter As SqlDataAdapter
 
    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim connectionString As String = _
                    "Integrated Security=SSPI;Persist Security Info=False;" + _
                    "Initial Catalog=Northwind;Data Source=.\sqlexpress"
        Dim selectCommand As String = "SELECT * FROM Employees"
 
        dataAdapter = New SqlDataAdapter(selectCommand, connectionString)
        Dim cmdBuilder As New SqlCommandBuilder(dataAdapter)
 
        dataAdapter.Fill(table)
        ListView1.DataContext = table
    End Sub
 
    Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        dataAdapter.Update(table)
    End Sub
End Class


このサンプルでは、サンプル「ListViewEditable」での使用方法に2点ほど追加している部分があります。
どちらもxmalコード部分ですが、ひとつは
Text="{Binding Path=Value,Mode=Twoway,RelativeSource =
          {RelativeSource TemplatedParent}}"
で、テンプレートの親のValueプロパティとバインドしている部分ですが、ここにMode=TwoWayを追加しています。これを追加しないと、入力した値をデータベースへ反映させることができません。


もう一つは
Width="{Binding Path=Width,Mode=Twoway,RelativeSource =
          {RelativeSource TemplatedParent}}">
<Editing:EditBox Value="{Binding Path=Title, Mode=TwoWay}"
  Height="25" Width="{Binding Path=Width, ElementName=gvColumn3}"/>
の部分で、これにより入力した値に合わせてTextBoxの幅が大きくなった場合に対応しています。





更新ボタンを押すことで、データベース上のデータも更新することができます。簡単なものであれば、この方法を使ってDataGridコントロールのようなUIを実現することが可能だと思います。