スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

カスタムMarkupExtensionを使った。使わずにはいられない。

System.Windows.Markup.MarkupExtensionクラスは、WPFでよく使われているクラスの1つだ。TemplateBindingやStaticResourceもその1つだったりする。
TemplateBindingExtension Class
StaticResourceExtension Class
日本語的には「マークアップ拡張」と呼ばれている。仕事では、多言語対応に使った。コードから指定言語のキャプション(文字列)を取得している。
参考にしたのは↓の記事。
Localization of a WPF application using a custom MarkupExtension
で、もう1つ、便利なマークアップ拡張があったので、取り入れてみた。
Binding to View Model properties in Data Templates. The RootBinding Markup Extension
このマークアップのキモは、Bindingのソースが必ずルートとなるコントロールのDataContext(ViewModel)となる事。これは、親となるコントロールのDataContext設定に影響されないという事だ。
これで思いついたのが、DataGridComboBoxColumnに使う事。
DataGridComboBoxColumnを使うとき、ItemsSourceの扱いについて困る事が多いんだけど、このマークアップを使う事で比較的簡単になる。使ってみるとその便利さがわかる。
○ItemsSourceのアイテムとなるクラスを作る。
using System;

namespace TawamureDays {

/// <summary>
/// コード+名称だけを保持するクラス
/// </summary>
/// <remarks>
/// コンボボックスの中身となります。
/// </remarks>
public class CodeNameData {

#region コンストラクタ

/// <summary>
/// コンストラクタ
/// </summary>
public CodeNameData() {
}

/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="newCode">コード</param>
/// <param name="newName">名称</param>
public CodeNameData(int newCode, string newName) {
this.Code = newCode;
this.Name = newName;
return;
}

#endregion

#region プロパティ

/// <summary>
/// コードを取得|設定します。
/// </summary>
public int Code {
get; set;
}

/// <summary>
/// 名称を取得します。
/// </summary>
public string Name {
get; set;
}

#endregion
}
}

○WindowVMに実装する。
using System;
using System.Collections.Generic;
using System.Windows;

namespace TawamureDays {

using TawamureDays.ViewModels;

/// <summary>
/// ウィンドウ用ViewModelクラス
/// </summary>
public class MainWindowVM : BaseWindowVM {

#region プロパティ

/// <summary>
/// ブックマークリストを取得します。
/// </summary>
public DataGridVM<BookmarkVM> BookmarkListVM {
get; private set;
}

/// <summary>
/// 種類リスト
/// </summary>
public IList<CodeNameData> KindList {
get; private set;
}


#endregion

#region BaseWindowVMメンバ

/// <summary>
/// Loadedイベントハンドラ
/// </summary>
/// <param name="parameter">パラメータ</param>
protected override void OnLoaded(object parameter) {
base.OnLoaded(parameter);

this.BookmarkListVM.ItemsSource.Add(new BookmarkVM());

this.KindList = new List<CodeNameData>(5) {
new CodeNameData(1, "ブログ"),
new CodeNameData(2, "掲示板"),
new CodeNameData(3, "ポータルサイト"),
new CodeNameData(4, "ベンダーサイト"),
new CodeNameData(5, "ホームページ"),
};

//変更された事を通知します(ターゲットに更新させる)。
this.NotifyPropertyChanged("KindList");


return;
}

#endregion
}
}

○DataGridのアイテムとなるクラスに、プロパティを追加する。
using System;
using System.Collections.Generic;
using System.Windows;

namespace TawamureDays {

using TawamureDays.ViewModels;

/// <summary>
/// ブックマークリストアイテム用ViewModelクラス
/// </summary>
public class BookmarkVM : BaseViewModel {

#region プロパティ

/// <summary>URL</summary>
private string url_;

/// <summary>
/// URLを取得|設定します。
/// </summary>
public string Url {
get {return url_;}
set {
if (url_ != value) {
url_ = value;
this.NotifyPropertyChanged("Url");
}
}
}

/// <summary>タイトル</summary>
private string title_;

/// <summary>
/// タイトルを取得|設定します。
/// </summary>
public string Title {
get { return title_; }
set {
if (title_ != value) {
title_ = value;
this.NotifyPropertyChanged("Title");
}
}
}

/// <summary>種類コード</summary>
private int? kindCode_;

/// <summary>
/// 種類コードを取得|設定します。
/// </summary>
public int? KindCode {
get { return kindCode_; }
set {
if (kindCode_ != value) {
kindCode_ = value;
this.NotifyPropertyChanged("KindCode");
}
}
}

/// <summary>種類名</summary>
private string kindName_;

/// <summary>
/// 種類名を取得|設定します。
/// </summary>
public string KindName {
get { return kindName_; }
set {
if (kindName_ != value) {
kindName_ = value;
this.NotifyPropertyChanged("KindName");
}
}
}

#endregion
}
}

○XAML側の設定を行う。
<Window x:Class="TawamureDays.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tw="http://schemas.tawamuredays.jp/wpf/gui"
Title="MainWindow" Height="350" Width="525">
<tw:TawamureContents>
<DataGrid DataContext="{Binding BookmarkListVM}"
ItemsSource="{Binding ItemsSource}"
CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTextColumn Header="URL"
tw:DataGridExtender.ColumnId="ColUrl"
Binding="{Binding Url}"
Width="4*"
/>
<DataGridTextColumn Header="TITLE"
tw:DataGridExtender.ColumnId="ColTitle"
Binding="{Binding Title}"
Width="6*"
/>
<DataGridComboBoxColumn Header="Kind"
tw:DataGridExtender.ColumnId="ColKind"
ItemsSource="{tw:RootBinding KindList}"
SelectedItemBinding="{Binding KindName}"
SelectedValueBinding="{Binding KindCode}"
SelectedValuePath="Code"
DisplayMemberPath="Name"
/>
</DataGrid.Columns>
</DataGrid>
</tw:TawamureContents>
</Window>

○実行
・初期状態
20121019_1

・編集モード
20121019_2
リストに追加した内容がちゃんと表示されている。

・編集終了
20121019_3
SelectedItemBindingでバインドしたプロパティの値が表示されている。
ん。DataGridComboBoxColumnのItemsSourceをどこに置くかを悩まずに済むだけでも使う価値があるかなと思う。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。