DataBinding でコントロールに値を表示

はじめに

DataBinding でウィンドウ上のコントロールに値を表示してみます。

バインドするクラスの作成

プロパティが変更されたことが通知されるように、INotifyPropertyChanged インタフェースを実装しました。

public class Item : INotifyPropertyChanged
{
    private string _fileName;

    public string FileName
    {
        get
        {
            return _fileName;
        }
        set
        {
            _fileName = value;
            OnPropertyChanged("FileName");
        }
    }

    private string _title;

    public string Title
    {
        get
        {
            return _title;
        }
        set
        {
            _title = value;
            OnPropertyChanged("Title");
        }
    }

    private string _icon;

    public string Icon
    {
        get
        {
            return _icon;
        }
        set
        {
            _icon = value;
            OnPropertyChanged("Icon");
        }
    }

    private string _workingDirectory;

    public string WorkingDirectory
    {
        get
        {
            return _workingDirectory;
        }
        set
        {
            _workingDirectory = value;
            OnPropertyChanged("WorkingDirectory");
        }
    }

    private string _arguments;

    public string Arguments
    {
        get
        {
            return _arguments;
        }
        set
        {
            _arguments = value;
            OnPropertyChanged("Arguments");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}|

XAML を記述

以前作成した XAML を流用。修正した箇所にはコメントを書いています。

<Window x:Class="WpfSample.EditDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="EditDialog" Height="400" Width="400" Background="#303030">
    <Window.Resources>
        <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
            <Setter Property="Margin" Value="2"/>
            <Setter Property="Height" Value="28" />
            <Setter Property="Foreground" Value="#F0F0F0"/>
            <Setter Property="Background" Value="#0593E2"/>
        </Style>
        <Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
            <Setter Property="Background" Value="#444444"/>
            <Setter Property="Foreground" Value="#F0F0F0"/>
            <Setter Property="Margin" Value="2"/>
            <Setter Property="Height" Value="28"/>
        </Style>
        <Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
            <Setter Property="Margin" Value="2"/>
            <Setter Property="Height" Value="28"/>
            <Setter Property="Background" Value="#444444"/>
            <Setter Property="Foreground" Value="#F0F0F0"/>
        </Style>
        <Style x:Key="{x:Type Label}" TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="#F0F0F0"/>
        </Style>
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" FlowDirection="RightToLeft">
            <Button Width="100" Content="キャンセル" />
            <Button Width="100" Content="OK" />
        </StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150"/>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="50" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Label Grid.Column="0" Grid.Row="0" Content="名前" />
            <Label Grid.Column="0" Grid.Row="1" Content="ファイル名" />
            <Label Grid.Column="0" Grid.Row="2" Content="パラメータ" />
            <Label Grid.Column="0" Grid.Row="3" Content="作業フォルダ" />
            <Label Grid.Column="0" Grid.Row="4" Content="実行時の大きさ" />
            <Label Grid.Column="0" Grid.Row="5" Content="ツールチップ" />
            <Label Grid.Column="0" Grid.Row="6" Content="ショートカットキー" />
            <Label Grid.Column="0" Grid.Row="7" Content="ホットキー" />

            <!--Itemクラスのプロパティをバインドする-->
            <TextBox Name="titleTextBox" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Title}" />
            <TextBox Name="fileNameTextBox" Grid.Column="1" Grid.Row="1" Text="{Binding FileName}"/>
            <TextBox Name="parameterTextBox" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Text="{Binding Arguments}" />
            <TextBox Name="workingDirTextBox" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="2" Text="{Binding WorkingDirectory}"/>

            <ComboBox Name="windowSizeComboBox" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="2" SelectedIndex="0" >
                <ComboBoxItem Content="通常のウィンドウ" />
                <ComboBoxItem Content="最大化" />
                <ComboBoxItem Content="最小化" />
            </ComboBox>
            <TextBox Name="toolTipTextBox" Grid.Column="1" Grid.Row="5" Grid.ColumnSpan="2" />
            <TextBox Name="shortcutKeyTextBox" Grid.Column="1" Grid.Row="6" />
            <TextBox Name="hotKeyTextBox" Grid.Column="1" Grid.Row="7"  />
            <Button Grid.Column="2" Grid.Row="1" Content="参照" />
            <Button Grid.Column="2" Grid.Row="6" Content="クリア" />
            <Button Grid.Column="2" Grid.Row="7" Content="クリア" />
        </Grid>
    </DockPanel>
</Window>

Binding の記述を追加しただけです。

オブジェクトを生成してバインド

今回はコンストラクタ内で済ませます。

/// <summary>
/// EditDialog.xaml の相互作用ロジック
/// </summary>
public partial class EditDialog : Window
{
    public EditDialog()
    {
        InitializeComponent();

        // パスは適当
        var item = new Item()
        {
            Title = "Firefox",
            FileName = @"C:\Program Files\Mozilla Firefox\Firefox.exe",
            WorkingDirectory = @"C:\Program Files\Mozilla Firefox\",
            Arguments = @"C:\Sample.html"
        };

        // コントロールにバインド
        titleTextBox.DataContext = item;
        fileNameTextBox.DataContext = item;
        workingDirTextBox.DataContext = item;
        parameterTextBox.DataContext = item;
    }
}

実行!

f:id:griefworker:20080920111620p:image
おおぉ!表示された!!

最後に

今回はコントロール1つ1つに Binding を指定しましたが、.NET Framework 3.5 SP1 で追加された BindingGroup を使うと、まとめてバインド可能とのこと。
次回は BindingGroup を使ってみます♪ (あっ、SP1 をインストールしないと!!)