#setlinebreak(on);
[[WP TIPS に戻る>wp7/tips]]
*ListBox に項目がないときのメッセージを簡単に表示する [#mca9c732]
サンプルプロジェクト [[ListBox_empty_message.zip>https://skydrive.live.com/redir.aspx?cid=793b87c06d2f0cd5&resid=793B87C06D2F0CD5!1916&parid=793B87C06D2F0CD5!223]]
サンプルプロジェクト [[ListBox_empty_message.zip>https://skydrive.live.com/redir.aspx?cid=793b87c06d2f0cd5&resid=793B87C06D2F0CD5!2169&parid=793B87C06D2F0CD5!223]]
#ref(listBox_empty_message-01.jpg,right,around,nolink);
WP7 ではソフトを開発しただけでは終わりません。最終的には AppHub にアプリを申請し通らなければ、野良アプリとして一生を終えてしまいかねません。
その AppHub 規約の中で ''「表示するコンテンツが無い場合は、その旨を表示する」'' というものがあるようです (Twitter で見かけた)。
たとえば ListBox 等で表示する項目が無い場合は、右の画像のようにメッセージを表示する必要があります。標準の Picture Hub などでも「同期していません。コンピュータに接続してビデオを同期させてください。」などのメッセージが表示されています。
いったいこれはどうすればいいのでしょうか?
#htmlinsert(u2b,id=2RJRLCc-8m4,width=480,height=360;)
**空の場合のメッセージの表示 [#u324879e]
空のメッセージを表示する方法として、まず ListBox に表示する項目が無い場合、ListBox にダミーの項目を表示しておくという手法が考えられます。
しかし本来のテンプレートとダミー項目のテンプレート双方を用意する必要がありますし、切り替えも面倒です。
ここで紹介する方法ではコンバータを使用して、空のメッセージを表示してみます。
考え方としては、
+ListBox の下に同じ大きさの StackPanel を配置、その中の TextBlock に空のメッセージを表示しておく。
+あとは ListBox.ItemSource.Count < 1 であれば ListBox.Visibility = Collapse, StackPanel.Visibility = Visible にして表示を切り替える。
とすれば項目数に合わせて ListBox, StackPanel の表示が相互に切り替わります。
**SourceItemVisibilityConverter の実装 [#y593c4f8]
以下は、SourceItemVisibilityConverter のソースコードです。
このコンバータは ICollection を引数(value)にとり、その格納数が 1 以上であれば、Visible を返し、それ以外なら Collapsed を返します。
つまり ''表示するアイテムがあれば Visible, なければ Collapsed'' を返すコンバータです。
これをプロジェクトに追加してビルドしておきます。
/// <summary>
/// 指定された ICollection が無ければ Collapse, あれば Visible を返す
/// </summary>
public class SourceItemVisibilityConverter : IValueConverter
{
// ListBox.Visibility にバインドされているコンバータ
public virtual object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// ICollection を取得→無ければ Collapsed
ICollection collection = value as ICollection;
if (collection == null)
return Visibility.Collapsed;
// アイテムがあれば Visible, なければ Collapsed
return collection.Count < 1 ? Visibility.Collapsed : Visibility.Visible;
}
public virtual object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
/// <summary>
/// SourceItemVisibilityConverter の逆
/// </summary>
public class SourceItemVisibilityInverseConverter : SourceItemVisibilityConverter
{
// ListBox.Visibility にバインドされているコンバータ
public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Visibility vis = (Visibility) base.Convert(value, targetType, parameter, culture);
return vis == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
**Blend でコンバータを配置する [#c8e75af0]
+次に Blend で以下のように、StackPanel, ListBox を配置します。
ListBox.ItemSource は、PhoneApplicationPage のメンバ Items が追加してあるので、それにバインドしています。
※ Blend になれていない方もいらっしゃると思いますので、バインド・コンバータの指定方法手順を書いておきます。
#ref(listBox_empty_message-02.jpg,nolink);
&br;
+ListBox の Visibility 右端の■をクリックしてデータバインドを選択します。
#ref(listBox_empty_message-03.jpg,nolink);
&br;
+「要素プロパティ」の「シーン要素」から PhoneApplicationPage を選択し、プロパティ Items を選択します。プロパティ一覧に表示されてない場合は、ドロップダウンメニューから「すべてのプロパティ」を選択してください。
#ref(listBox_empty_message-04.jpg,nolink);
&br;
+ダイアログボックスの下矢印をクリックして、ボックスを広げます。「値コンバータ」の欄の「...」ボタンを押します。
#ref(listBox_empty_message-05.jpg,nolink);
&br;
+追加できるコンバータの一覧が表示されますので「SourceItemVisibilityConverter」を選択します。
※ここに出てこない場合は SourceItemVisibilityConverter.cs が追加されてないか、ビルドされていない場合です。
#ref(listBox_empty_message-06.jpg,nolink);
&br;
+これで完了です。OK ボタンを押してください。
#ref(listBox_empty_message-07.jpg,nolink);
ここまでの操作で、ListBox.ItemSource のバインド元 Items の値に合わせて、ListBox が表示・非表示されるようになりました。
しかしこのままだと ListBox の下にある StackPanel が透けてしまい、右の画像のようになってしまいます。
この対処方法は、
+ListBox.Background を Transparent 以外にする
+StackPanel.Visibility に ListBox と同じくコンバータを設定する。
の2つの方法があります。
#ref(listBox_empty_message-08.jpg,right,around,nolink);
ListBox.Background を Transparent 以外にするのは、安直な方法ですがここでは StackPanel.Visibility にもコンバータを設定して表示・非表示を切り替えた方が良さそうです。
StackPanel.Visibility にコンバータを設定するには、ListBox と同じように Items のバインドからコンバータを指定します。ただしコンバータの選択では、SourceItemVisibilityConverter ではなく SourceItemVisibilityInverseConverter を選択して、ListBox とは逆の Visibility が設定されるようにしてください。
*参考 [#ge894518]
[[Application Certification Requirements for Windows Phone>http://msdn.microsoft.com/en-us/library/hh184843%28v=VS.92%29.aspx]]