2017年9月7日
WPF
技術情報

SPREAD for WPF 2.0J 新機能紹介(3)- よりWPFらしく – MVVM対応を強化

こんにちは!WPF担当の高橋です。ここまで「よりExcelライクに」をテーマに新機能をご紹介してきました:

今日は少し違う視点で、「よりWPFらしく」をテーマに、新バージョンで可能になった、セルのバインディングをご紹介したいと思います。

MVVM対応の強化

本ブログでもご紹介したCodeZineの記事「SPREAD for WPFでMVVMパターンのアプリケーションを作成する」にもあるように、SPREADは旧バージョンにおいても、MVVMパターンに対応しています。ただし、新バージョンでは更にMVVM対応を強化しました。それが、セルのバインディングです。

セルのバインディング

セルのスタイルをXAMLで設定するにはCellPresenterクラスを使用しますが、2.0Jでは、セルの値を表すValueプロパティが、依存関係プロパティとして提供されるようになりました。

WPFでバインディングが機能するのは依存関係プロパティです。
Valueプロパティが依存関係プロパティとして提供されることにより、セルの値に応じて、XAMLでセルのスタイルを変更できるようになりました。こうした処理をXAMLで記述することにより、コードビハインドの記述を軽減できます。

MVVMの実装では、コードビハインドに出来るだけ処理を記述せず、ビューとビューモデルがWPFのバインディングで対話することを要望されるお客様は少なくありません。そうしたお客様に、ぜひご活用いただきたい機能です。

セルのバインディングの使用例を、1つご紹介したいと思います。

コンボボックスの値に応じてセルの外観を変更

以下のサンプルでは、ウィンドウにコンボボックスとSPREADが配置されています。
SPREADは、お客様から受けた問い合わせを一覧で表示し、コンボボックスには、期間を表す値が設定されています。コンボボックスで選択された値に応じて、該当するSPREADのセルを、文字を赤色に変更して強調表示します。

ozu170831_1

このアプリケーションを構成するMVVM(モデル・ビュー・ビューモデル)の各要素は以下のとおりです。

モデル

モデルは、問合せを表すCustomerRequestクラスです。

Visual Basic
Public Class CustomerRequest
    Public Property ID() As String
    Public Property Title() As String
    Public Property OpenDate() As DateTime
    Public Property Note() As String

End Class
C#
public class CustomerRequest
{
    public string ID { get; set; }
    public string Title { get; set; }
    public DateTime OpenDate { get; set; }
    public string Note { get; set; } 
}

※ここではコードの主要部分をご紹介します。本記事の最後にサンプルプロジェクトのダウンロードリンクがあります。

ビューモデル

ビューモデルのCustomerRequestViewModelクラスは、次の2つのプロパティをもちます。

  • 問合せのコレクション(CustomerRequestsプロパティ)
  • 強調表示する期間(FocusDaysプロパティ)
Visual Basic
Public Class CustomerRequestViewModel
    Implements INotifyPropertyChanged
    Private _requests As ObservableCollection(Of CustomerRequest)
    Public Sub New()
        _requests = (New CustomerRequestCollection()).GetCustomerRequests()
    End Sub
    Public Property CustomerRequests() As ObservableCollection(Of CustomerRequest)
        Get
            Return _requests
        End Get
        Set
            If Not _requests.Equals(Value) Then
                _requests = Value
                NotifyPropertyChanged("CustomerRequests")
            End If
        End Set
    End Property
    Private _days As Integer
    Public Property FocusDays() As Integer
        Get
            Return _days
        End Get
        Set
            If _days <> Value Then
                _days = Value
                NotifyPropertyChanged("FocusDays")
            End If
        End Set
    End Property

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    Private Sub NotifyPropertyChanged(propertyName As [String])
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub
End Class
C#
public class CustomerRequestViewModel : INotifyPropertyChanged
{
    // 問合せのコレクション
    private ObservableCollection<CustomerRequest> _requests;
    public CustomerRequestViewModel()
    {
        _requests = (new CustomerRequestCollection()).GetCustomerRequests();
    }
    public ObservableCollection<CustomerRequest> CustomerRequests
    {
        get { return _requests; }
        set
        {
            if (_requests != value)
            {
                _requests = value;
                NotifyPropertyChanged("CustomerRequests");
            }
        }
    }
    // 強調する期間
    private int _days;
    public int FocusDays
    {
        get { return _days; }
        set
        {
            if (_days != value)
            {
                _days = value;
                NotifyPropertyChanged("FocusDays");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

また、ビューとのバインディングで使用するコンバーターを作成します。コンバーターは、SPREADのセルと、強調表示する期間の2つの値を扱えるよう、IMultiValueConverterインタフェースを実装します。

Visual Basic
Public Class FocusDaysConverter
    Implements IMultiValueConverter
    Public Function Convert(values As Object(), targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
        Dim result As Boolean = False
        If TypeOf values(0) Is DateTime Then
            Dim [date] As DateTime = DirectCast(values(0), DateTime)
            If values(1) IsNot Nothing Then
                Dim days As Integer = Integer.Parse(values(1).ToString())
                result = DateTime.Today.Subtract([date]).Days < days
            End If
        End If
        Return result
    End Function

    Public Function ConvertBack(value As Object, targetTypes As Type(), parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class
C#
public class FocusDaysConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        bool result = false;
        if (values[0] is DateTime)
        {
            // SPREADセルの日付値
            DateTime date = (DateTime)values[0];
            if (values[1] != null)
            {
                // 強調する期間に該当するか
                int days = int.Parse(values[1].ToString());
                result = DateTime.Today.Subtract(date).Days < days;
            }
        }
        return result;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

ビュー

ビューは、WPFのウィンドウを表すMainWindow.xamlと、そのコードビハインド(MainWindow.xaml.csまたはMainWindow.xaml.vb)です。

ウィンドウのDataContextプロパティにビューモデルを設定します。
これで、ウィンドウのコンボボックスとSPREADに、ビューモデルのプロパティをバインドできます。

<Window.DataContext>
    <!--ビューモデルを設定-->
    <local:CustomerRequestViewModel/>
</Window.DataContext>
コンボボックス

コンボボックスで選択された値が、強調表示する期間です。
これを実現するために、コンボボックスのSelectedValueプロパティを、ビューモデルのFocusDaysプロパティにバインドします。

<!--選択された値をビューモデルのFocusDaysプロパティにバインド-->
<ComboBox SelectedValue="{Binding FocusDays, Mode=TwoWay}" …省略…>
SPREAD

SPREADには問い合わせのコレクションを表示します。
これを実現するために、SPREADのItemsSourceプロパティを、ビューモデルのCustomerRequestsプロパティにバインドします。
また、強調表示する期間に該当するセルの文字を赤色に変更します。
これを実現するために、SPREADのCellStyleプロパティにDataTriggerを設定します。MultiBindingを使用して、セルの値と、ビューモデルのFocusDaysプロパティをバインドします。

<sg:GcSpreadGrid ItemsSource="{Binding CustomerRequests}" …省略…>
    <!--セルのバインディングを設定-->
    <sg:GcSpreadGrid.CellStyle>
        <Style TargetType="{x:Type sg:CellPresenter}">
            <Style.Triggers>
                <DataTrigger Value="True">
                    <DataTrigger.Binding>
                        <MultiBinding Converter="{StaticResource FocusDaysConverter}">
                            <!--セルの値-->
                            <Binding RelativeSource="{RelativeSource Self}" Path="Value"/>
                            <!--ビューモデルのFocusDaysプロパティ-->
                            <Binding Path="FocusDays"/>
                        </MultiBinding>
                    </DataTrigger.Binding>
                    <Setter Property="FontWeight" Value="Bold"/>
                    <Setter Property="FontSize" Value="13"/>
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </sg:GcSpreadGrid.CellStyle>
    <sg:GcSpreadGrid.Columns …以降、省略…
</sg:GcSpreadGrid>

実行

アプリケーションを実行してみましょう。コンボボックスの値に応じて、対象のセルの文字が赤色に変化します。

ozu170831_2

サンプルプロジェクト

本記事のサンプルプロジェクトを、こちらからダウンロードできます。

2017年10月6日 開催 「グレープシティECHO Tokyo 2017」

「よりWPFらしく」をテーマに新機能をご紹介しましたが、グレープシティでは「XAML」をテーマにイベントを開催します。

</>XAMLエキスパートが集結!- GrapeCity ECHO Tokyo 2017 開催 –

※本イベントですが、大変ありがたいことに満席(100名)となりました。誠に恐れ入りますが、参加ご希望の方はキャンセル待ちへのご登録をお願いいたします。

2017年9月7日
HTML5/JavaScript
お知らせ

「SpreadJS/Wijmo」が「OutSystems Rich Grid Component Edition」に採用

グレープシティは、株式会社BlueMemeが販売する超高速開発基盤用コンポーネント「OutSystems Rich Grid Component Edition」に、「SpreadJS/Wijmo」が採用されたことを発表しました。
 
ニュースリリースの詳細を見る

2017年9月7日
HTML5/JavaScript
イベント

9月下旬も続々 – イベント出展します

9月22日(金)は「Developers Summit 2017 KYUSYU」(通称「デブサミ九州」)、
24日(日)は「HTML5 Conference 2017」に出展いたします。

イベントでは、Webアプリケーションで高度なUIを実現するHTML5/JavaScriptライブラリ、「Wijmo(ウィジモ:エンタープライズアプリケーションの開発用コントロールセット)」と、今月末(9月27日)に新しく発売されるSpreadJSをご紹介します。

新しいSpreadJSは、これまでのExcel互換高機能スプレッドシートの後継となるSpread.Sheetsに、グリッドはじめ多彩なデータレイアウトを実現する新しいコントロールSpread.Viewsが加わった、2つのコントロールを収録した新製品です。

新しいSpreadJSについて詳しく見る

以下、各イベントの詳細です。

Developers Summit 2017 KYUSYU

公式イベントページはこちら

会期 2017年9月22日(金) 10:30~18:15(受付開始:10:00~)
主催 株式会社 翔泳社
会場 アクロス福岡
費用 無料(事前登録制)

HTML5 Conference 2017

公式イベントページはこちら

会期 2017年9月24日(日) 10:00~19:30(受付開始:9:30~)
主催 html5j
会場 東京電機大学 千住キャンパス
費用 無料(事前登録制)

皆さまにお会いできるのを楽しみにしています。
ぜひグレープシティブースまでお越しください。

2017年9月1日
お知らせ

メンテナンスによる一部サービス停止のお知らせ

メンテナンスのため、サイトの一部が機能停止いたします。
お客さまにはご迷惑をおかけいたしますが、ご了承くださいますようお願い申し上げます。

期間

2017年9月3日(日)9:00~18:00 予定

対象サイト

  • GrapeCity Developer Tools サイト

上記以外のサイトにつきましては通常通りの提供となります。

2017年9月1日
HTML5/JavaScript
イベント

デブサミ関西に出展します

関西ITエンジニアの祭典「Developers Summit 2017 KANSAI」、通称「デブサミ関西」に、グレープシティは今年も出展いたします。グレープシティブースでは、Webアプリケーションで高度なUIを実現するHTML5/JavaScriptライブラリ2製品を紹介します。

一つは、「Wijmo(ウィジモ:エンタープライズアプリケーションの開発用コントロールセット)」、そしてもう一つは、今月末(9月27日)に新しく発売されるSpreadJSです!

新しいSpreadJSは、これまでのExcel互換高機能スプレッドシートの後継となるSpread.Sheetsに、グリッドはじめ多彩なデータレイアウトを実現する新しいコントロールSpread.Viewsが加わった、2つのコントロールを収録した新製品です。

新しいSpreadJSについて詳しく見る

エンジニアの皆さまは、どんな時に「成長した」と感じられますか?プロジェクトを成功させたとき、困難を乗り越えたとき……さまざまな瞬間があると思いますが、新しいモノとの出会いもその一つです。
エンジニアが、新しいモノと出会うこと。そして行動を起こすこと。それがエンジニア自身の成長に繋がり、ひいてはビジネスや企業、世の中にいい影響を及ぼす。新しい未来を作っていく。そのきっかけとなりたい、それが今年のデブサミ関西2017です。

新しいSpreadJSをたずさえて、関西の皆さまとお会いできるのを楽しみにしています!
ぜひ弊社ブースまでお越しください。

公式イベントページはこちら

会期 2017年9月8日(金) 10:30~17:30(受付開始:10:00~)
主催 株式会社 翔泳社
会場 神戸国際会議場(兵庫・神戸)
<アクセス> 三宮からポートライナー乗車10分 市民広場駅下車すぐ
費用 無料(事前登録制)
前のページ 次のページ