2011年10月10日月曜日

◆ConverterとFocusイベントを使って表示形式をカスタマイズする

簡単に全体の機能を触ってみて気になるのが、表示項目の形式を簡単に変えられないこと。
また、入力項目のValidationも一応コーディングのインタフェースは標準で用意されているが、
image
昨今のアプリケーションであれば、ある程度のValidationはノンコーディングで可能になっていることを考えると、簡単さが売りと思われるLightSwitchで必ず(必須、最大長以外)コーディングが必要になるのは残念だ。

Validationはとりあえずコーディングインタフェースがあるから良いとしても表示形式を調整できないのはちょっと困る。

という事で、表示形式のカスタマイズ方法を探ってみた。
基本的にはLightSwitchもWPFアプリなのだろうからコンバーターとかを使うのかと思い、とりあえず以下のように実現した。
LightSwitchに関してはまだ情報も少なく、これが妥当なやり方なのかも判らないが一応こんな方法でも出来たよと言う事で。

<データ>

いつものように、NorthwindのCustomersをデータソースに使用。

<画面>

Customersをデータソースに、「一覧および詳細画面」のテンプレートを使って画面を作る。
コントロールツリーの「CustomersItemDetails」で「追加」ボタンをクリックし「新しいカスタムコントロール」をクリックする。

image

以下のネームスペースを展開して「TextBox」コントロールを追加する。
imageimage

ここでは「Country2」という名前にした。
image
 

ツールバーの「コードの記述」から「CustomersListDetail_Created」をクリックしてコードエディタを開く。

image

表示された「コードエディタ」にて以下のようなコーディングを追加した。

    public partial class CustomersListDetail
{
partial void CustomersListDetail_Created()
{
// ここにコードを書き込んでください。
this.FindControl("Country2").SetBinding(TextBox.TextProperty,
"Screen.Customers.SelectedItem.Country",
new CountryConverter(),
System.Windows.Data.BindingMode.TwoWay);

this.FindControl("Country2").ControlAvailable += Country2FieldAvailable;

}


private void Country2FieldAvailable(object sender, ControlAvailableEventArgs e)
{
((System.Windows.Controls.Control)e.Control).GotFocus += Country2GotFocus;
((System.Windows.Controls.Control)e.Control).LostFocus += Country2LostFocus;
}

private void Country2GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
var txtObj = (System.Windows.Controls.TextBox)sender;
txtObj.Text = (string)(new CountryConverter()).ConvertBack(txtObj.Text, null, null, null);

((System.Windows.Controls.TextBox)sender).SelectAll();
}

private void Country2LostFocus(object sender, System.Windows.RoutedEventArgs e)
{
var txtObj = (System.Windows.Controls.TextBox)sender;
txtObj.Text = (string)(new CountryConverter()).Convert(txtObj.Text, null, null, null);

}

class CountryConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return "(" + value + ")";
}

public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return (((string)value).Replace("(", "")).Replace(")", "");
}
}

}

6行目から9行目で「Country2」コントロールを検索し、Textプロパティに「Country」の値をバインドしている。
その時、コンバータとして自前の「CountryConverter」を指定。


また、Focusに応じても表示を切り替えたいので「GotFocus」と「LostFocus」にイベントハンドラーを登録する。
登録するタイミングとして、コントロールが有効になった後に行う必要があるようなので一旦11行目で「ControlAvailable」イベントを拾って、そこで登録処理を行う。


あとはConverterクラスを追加して「Convert」メソッドと「ConvertBack」を実装すればOKだ。
ここでは動作の確認だけなので便宜的に「Country」に括弧をつけて表示させている。


これで実行すると以下のような感じになる。


imageimage


とりあえず良い感じだが、ちょっとフォーマットしたいだけの要求には大げさな感じ。


もう少しなんとかならないものだろうか・・・。

0 件のコメント:

コメントを投稿