#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]]