[Silverlight][Tips] ファイルダイアログを使用して画像を表示する

今回は、ファイルダイアログを使用して画像を選択し、表示する方法について見ていきます。

デザインは以下のようにします。

デザイン

XAMLは以下の通りです。

<Grid x:Name="LayoutRoot" Background="White">
    <Button x:Name="btnOpenFile" Content="Button" 
            HorizontalAlignment="Left" Margin="10,10,0,0" 
            VerticalAlignment="Top" Width="75" 
            Click="btnOpenFile_Click"/>
            
    <Image x:Name="imgPicture" HorizontalAlignment="Left" 
           Height="224" Margin="10,57,0,0" 
           VerticalAlignment="Top" Width="358"/>
</Grid>

ボタンクリック時のコードを以下に示します。

VB.NETの例

Imports System.Windows.Media.Imaging

Private Sub btnOpenFile_Click(sender As Object, e As RoutedEventArgs)
    Dim dlgOpen = New OpenFileDialog()

    If dlgOpen.ShowDialog() = True Then
        Dim image = New BitmapImage()
        image.SetSource(dlgOpen.File.OpenRead())
        imgPicture.Source = image
    End If
End Sub

C#の例

using System.Windows.Media.Imaging;

/// <summary>
/// ボタンクリック時の処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpenFile_Click(object sender, RoutedEventArgs e)
{
    var dlgOpen = new OpenFileDialog();

    if ( dlgOpen.ShowDialog() == true )
    {
        var image = new BitmapImage();
        image.SetSource(dlgOpen.File.OpenRead());
        imgPicture.Source = image;
    }
}

ファイルファイアログを使用するには OpenFileDialogクラスを使用し、ダイアログを表示するには ShowDialogメソッドを使用します。

ShowDialogメソッドは、ファイルが選択された場合に true を返します。

if 文を使用して、ファイルが選択されたことを判断したら、次にイメージを表示します。

コード中の image.SetSource の部分は、BitmapImageクラス(画像を取り扱うクラスです)のインスタンスの SetSourceメソッドに ファイルダイアログで選択されたファイルのストリームを渡しています。

最後に、イメージの表示を行います。、MainPage.xamlに配置した Imageコントロールの Sourceプロパティに、先ほどのBitmapImageのインスタンスをセットします。

 

実行結果イメージは下記の通りです。

実行結果例

[Silverlight][バインディング] Blendを使ってサンプルデータをバインディングする

今回は Visual Studio ではなく、Blendを使用して Silverlightのサンプルアプリケーションを作成します。(ノンコーディングなので、今回の操作はVB.NETもC#も共通です)

まずは Blendを起動し「新規プロジェクト」をクリックします。

Blendを起動

「新しいプロジェクト」ダイアログが開くので、「Silverlightアプリケーション」を選択し[OK]ボタンをクリックします。(名前や場所は自由に付けてください)

サンプルプロジェクトの作成

次に「アセット」タブを選択して、「コントロール」の中からListBoxを見つけ、MainPage.xaml にドラッグ&ドロップをします。ListBoxのサイズは適当に設定しておきます。

ListBoxの配置

ここからサンプルデータの作成に入ります。

最初に「データ」タブを選択します。

次に、どこにサンプルデータを作成するかを選択するのですが今回はプロジェクト全体で使えるようにする「プロジェクト」を選択状態にし、「サンプルデータの作成」ボタンをクリックします。開いているドキュメントだけで使用する場合は「このドキュメント」を選択します。

サンプルデータの作成

「新しいサンプルデータ」をクリックします。

「新しいサンプルデータ」を選択

 

「新しいサンプルデータ」ダイアログが表示されるので、データソース名を入力し[OK]ボタンをクリックします。今回はデフォルトのままとします。

データソース名を設定する

追加したデータソースにはコレクションがあり、2つのプロパティがあることを確認できます。

コレクションとプロパティが2つあることを確認

Collectionにぶら下がっている2つのプロパティの名前を「Img」と「Name」に変更します(プロパティ名を変更するには、表示されているプロパティ名をゆっくりと2回クリックします。文字を入力できるようになるので、元々のプロパティ名を削除して新しい名称を入力します。)

プロパティ名の変更

次に、「Img」と「Name」のデータ型を変更します。

「Img」プロパティは「イメージ型」に変更します。場所には、サンプルで使用するイメージが格納されているフォルダを指定します。サンプルイメージを持っていない場合は空欄にします。

空欄にすると Blendが持っているサンプルイメージが使用されるようになります。

今回は「場所」は空欄にしておきます。

「Img」プロパティのデータ型を「イメージ」に変更

 

「Name」プロパティは、文字列型にし、形式に「名前」を指定します。形式にはいくつか種類があるので、サンプルとしてふさわしいものを選択してください。「名前」を選択した場合は人の名前がサンプルデータとして設定されます。

データ型を文字列型にし、形式に「名前」を設定

 

ここまでできたら、SampleDataSource にある Collection を ListBoxにドラッグ&ドロップします。

CollectionをListBoxにドラッグ&ドロップ

すると、ListBoxにはサンプルデータが表示されます。

サンプルデータが表示されたListBox

それでは、実行してみましょう。

実行例

ブラウザでもサンプルデータが表示されます。

このように、データを一から準備する必要はなく、簡単にサンプルデータを作成することができます。

[Silverlight][バインディング] ComboBoxへのデータ表示

Silverlight のComboBoxへの最も簡単なデータの表示は、XAMLコードによるものだと思います。

たとえば「Eric」「Paul」「Billy」「Pat」というデータ表示するXAMLコードは以下のようになります。

ComboBoxにデータを表示するXAMLコードの例

    <ComboBox HorizontalAlignment="Left" Margin="10,10,0,0" 
        VerticalAlignment="Top" Width="120">
        
        <ComboBoxItem Content="Eric" />
        <ComboBoxItem Content="Paul" />
        <ComboBoxItem Content="Billy" />
        <ComboBoxItem Content="Pat" />
        
    </ComboBox>

 

データ数が少なく固定化されたデータであれば上記でも十分かと思います。
しかし、表示値以外に内部値も持たせる場合はどうでしょうか。

例えば社員名と社員番号を持つリストを表示させたいとしましょう。

社員名をコンボボックスに表示させ、内部値として社員IDを持たせる場合を考えます。

この場合は、XAMLだけで表現するよりもデータバインドを利用した方が効率が良さそうです。

まずは、社員情報を表すEmployee クラスを作成します。

VB.NET(Employee.vb)

Private _empData As ObservableCollection(Of Employee)

Public Class EmployeeData

    Public Property Id As Integer

    Public Property Name As String

End Class

C#(Employee.vb)

namespace SampleComboBoxCS
{
    public class Employee 
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

次に、上記で作成した Employeeクラスを使用して4人分のデータを作成し、MainPage のDataContextへバインドします。

以下は MainPage でのコード例です。

VB.NET(MainPage.xaml.vb の Sub Newを抜粋)

Public Sub New()
    InitializeComponent()

    _empData = New ObservableCollection(Of Employee)() From
    {
        New Employee() With {.Id = 1, .Name = "Eric"},
        New Employee() With {.Id = 2, .Name = "Paul"},
        New Employee() With {.Id = 3, .Name = "Billy"},
        New Employee() With {.Id = 4, .Name = "Pat"}
    }

    Me.DataContext = _empData
End Sub

C#(MainPage.xaml.cs の mainを抜粋)

private ObservableCollection<Employee> _empData;

public MainPage()
{
    InitializeComponent();

    _empData = new ObservableCollection<Employee>()
    {
        new Employee { Id = 1, Name = "Eric"},
        new Employee { Id = 2, Name = "Paul"},
        new Employee { Id = 3, Name = "Billy"},
        new Employee { Id = 4, Name = "Pat"},
    };

    this.DataContext = _empData;
}

ObservableCollectionクラスは、System.Collections.ObjectModel名前空間にあるクラスです。
このクラスはコレクションに対する挿入・削除・設定を行った場合にそれらの変更をクラス外部にイベントとして通知することができるようになってます。ObservableCollectionクラスは、ユーザーインターフェイスとコレクションを同期したい場合などに使用されます。

さて、4人分のデータを作成し、MainPageへバインドすることができました。

今度は、MainPage.xaml を開いて ComboBoxを1つ貼り付け、XAMLのコード(ComboBox部分)を以下のようにします。

MainPage.xaml(ComboBox部分のみ抜粋)

<ComboBox HorizontalAlignment="Left" 
          Margin="10,10,0,0" VerticalAlignment="Top" 
          Width="120"
          ItemsSource="{Binding}" SelectedValuePath="Id" 
          DisplayMemberPath="Name" />

上記のXAMLでは

  • ItemSource 部分でデータをバインディング
  • SelectedValuePath 部分でバインドされているデータのId項目をセット
  • DisplayMemberPath 部分でバインドされているデータのName項目をセット

ということを行っています。

SelectedValuePathが内部値を、DisplayMemberPathが表示値を管理するプロパティです。

ここまでできたら実行して見ます。

実行結果は以下の通りで、ComboBoxには4人分のデータがセットされていることを確認できます。

実行例

ComboBoxにデータを表示する手順がわかりました。

最後に、ComboBox で表示した名前に対する内部値が正しく選択されているかを確認してみます。

MainPage.xamlを開き、 CobmoBoxに「cmbName」という名前を付けます。次に ComboBoxの下に TextBlockコントロールを1つ貼り付け XAMLコードを以下のように修正します。

<ComboBox x:Name="cmbName" HorizontalAlignment="Left" 
           Margin="10,10,0,0" VerticalAlignment="Top" 
           Width="120"
           ItemsSource="{Binding}" SelectedValuePath="Id" 
           DisplayMemberPath="Name" />
<TextBlock HorizontalAlignment="Left" Margin="10,35,0,0" 
           TextWrapping="Wrap"  VerticalAlignment="Top"
           Text="{Binding ElementName=cmbName, 
           Path=SelectedItem.Id, Mode=OneWay}"/>

ここで注意して見ていただきたいのは TextBlockの Textプロパティ部分です。

まず、ElementNameにcmbNameを指定し、ComboBoxをデータソースとします。 Pathには SelectedItem.Idを指定し、ComboBoxで選択されている項目のIdが表示されるようにしています。

実行結果は以下の通りです。

表示されている Billyは Id = 3 なので、正しく動作していることを確認できます。

実行結果2

 

[Silverlight][バインディング] データバインディングのモードを理解する

今回はデータバインディングのモードについて説明します。

まずは、Silverlightアプリケーションを作成し、MainPage.xamlに NumericUpDownコントロールと Sliderコントロールを貼り付けます。
NumericUpDownコントロールはSilverlight Toolkitに含まれるコントロールです。
Silverlight Toolkitがインストr-ルされていない場合は、前回の記事を参照ください。

メインページのデザイン

モードについて
データバインディングのモードをを設定すると、一方のコントロールの値を変更した時に、もう一方のコントロールの値を連動して更新することができるようになります。
今回の例では、NumeriUpDown と SliderのValueプロパティを連動させます。

モードは以下のように3種類あります。

モード値 説明
 OneTime ソースの値が1度だけターゲットに対して反映されます
 OneWay ソースの値が変更されると、ターゲット側の値も変更されます
 TwoWay ソースの値が変更されると、ターゲット側の値も変更されます。また、ターゲットの値が変更されるとソース側の値が変更されます

OneTimeの検証

OneTimeの検証をするために、XAMLを以下のように編集します。

<toolkit:NumericUpDown x:Name="NumericUpDown1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="114" Value="50"/>
<Slider x:Name="Slider1" HorizontalAlignment="Left" Margin="10,37,0,0" VerticalAlignment="Top" Width="252"
        Minimum="0" Maximum="100" Value="{Binding ElementName=NumericUpDown1, Path=Value, Mode=OwoTime}"/>

NumericUpDown では 初期値として Valueプロパティに「50」を設定しています。
Sliderコントロールでは、ValueプロパティにNumericUpDownのValueプロパティをバインディングし、ModeプロパティにOnwWayを指定しています。

実行すると、NumericUpDownコントロールには「50」が表示され、Sliderコントロールのつまみは中心の50の位置に表示されます。

モードがOneTimeのため、表示された移行、NumericUpDownの値を変更しても Sliderコントロールの値は変更されません
また、Sliderコントロールの値を変更してもNumericUpDownの値も変更されません。


OneWay

OneWayの検証をするために、XAMLを以下のように編集します。

<toolkit:NumericUpDown x:Name="NumericUpDown1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="114" Value="50"/>
<Slider x:Name="Slider1" HorizontalAlignment="Left" Margin="10,37,0,0" VerticalAlignment="Top" Width="252"
        Minimum="0" Maximum="100" Value="{Binding ElementName=NumericUpDown1, Path=Value, Mode=OneWay}"/>

OneTimeのときとの違いは、Modeプロパティが「OneWay」となっている部分です。

実行すると、NumericUpDownコントロールには「50」が表示され、Sliderコントロールのつまみは中心の50の位置に表示されます。
NumericUpDownの値を変更すると、連動してSliderのつまみが移動します。
Sliderのつまみを移動してもNumericUpDownの値は変更されないことを確認しましょう。


TwoWay

TwoWayの検証をするために、XAMLを以下のように編集します。

<toolkit:NumericUpDown x:Name="NumericUpDown1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="114" Value="50"/>
<Slider x:Name="Slider1" HorizontalAlignment="Left" Margin="10,37,0,0" VerticalAlignment="Top" Width="252"
        Minimum="0" Maximum="100" Value="{Binding ElementName=NumericUpDown1, Path=Value, Mode=TwoWay}"/>

OneTIme, OneWayのときとの違いは、Modeプロパティが「TwoWay」となっている部分です。

実行すると、NumericUpDownコントロールには「50」が表示され、Sliderコントロールのつまみは中心の50の位置に表示されます。
NumericUpDownの値を変更すると、連動してSliderのつまみが移動します。
また、Sliderのつまみを移動すると、連動してNumericUpDownの値が変更されます。

[Silverlight][バインディング] コントロール間のバインディング2

前回はXAMLコードを編集してデータバインディングを設定しました。

今回は前回と同様のことをXAMLコードを編集せずにプロパティウィンドウから設定します。


1.コントロールの配置とプロパティの設定

前回と同様にプログレスバーコントロールとスライダーコントロールを配置し、

プログレスバーのプロパティ Minimum = 0, Maximum = 100

スライダーのプロパティ Minimum = 0, Maximum = 100

に設定します。


 2.バインディング設定

プログレスバーを選択して、プロパティウィンドウで Valueプロパティの右側にある□をクリックします。

すると、メニューが表示されるので「データバインディングの作成」を選択します。

データバインディングの作成

「[Progressbar].Value」のデータバインディングを作成」ダイアログが表示されます。

バインディングの設定

 

このダイアログでは、プログレスバーのValueプロパティにバインディングする項目を設定するためのものです。

バインドの種類では「ElementName」を選択します。

要素名では「Slider」を選択します。

パスでは「Value」を選択し、最後に[OK]ボタンをクリックします。

このことからもわかるように、プログレスバーのValueプロパティに、スライダーコントロールのValueをビンディングしたことになります。


3.実行して確認する

以上で設定は終わりです。

実行して確認してみましょう。

スライダーコントロールのつまみと連動して、プログレスバーの値が変化することが確認できます。

実行確認