kazuakix の日記

Windows Phone とか好きです

Windows Phone でユーザーコントロールを作ってみる (2)

またまた昨日の続き。

ユーザーコントロールに依存関係プロパティを追加することで、値が変更されたときに自動的にコントロールの表示が更新されるようになりました。でも、表示を更新するだけじゃなくて別の動作をさせたい事もありますよね、

なので、依存関係プロパティにもう少し細工をしてやります。

PropertyChangedCallback デリゲートの追加

昨日の感じで 新たに Num という依存関係プロパティを追加します。

TAB を押しながら 型・プロパティ名・親クラスを変更して、最後に PropertyMetadata の中で初期値 0 に続けて 「, new」と入れてスペースを押します。

自動的に PropertyChangedCallback が候補に表示されるので TAB で確定させて続けて「(OnNumChanged」とタイプします。カッコの中はこれから作るメソッドなので名前はなんでもいいです。

f:id:kazuakix:20140906205945j:plain

当然ながら勝手に名前だけ書いたメソッドは定義が無いので、右クリックして「生成」-「メソッドスタブ」で作成します。これが値が変更されたときに呼び出されるメソッドになります。

f:id:kazuakix:20140906213403j:plain

ここまででこんな感じになりました。

public int Num
{
    get { return (int)GetValue(NumProperty); }
    set { SetValue(NumProperty, value); }
}

// Using a DependencyProperty as the backing store for Num.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty NumProperty =
    DependencyProperty.Register("Num", typeof(int), typeof(PopupPanel), new PropertyMetadata(0, new PropertyChangedCallback(OnNumChanged)));

private static void OnNumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    throw new NotImplementedException();
}    

 

PropertyChangedCallback デリゲートの中身を作る

作成された OnNumChanged は static メソッドになります。
実際に値が変更されたインスタンスは 引数の d 、変更された値は e.OldValue と e.NewValue にセットされてきます。

以下は Num プロパティで受け取った値をもとに昨日の TitleText プロパティを更新するようにする例です。せっかくなので値によってちょっとだけ処理を分けるようにしてみました。

private static void OnNumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var popupPanel = d as PopupPanel;

    var num = (int)e.NewValue;
    if (IsPrime(num))
    {
        popupPanel.TitleText = "ウォォォォーーーーー!!!!!";
    }
    else
    {
        popupPanel.TitleText = "Popup " + num.ToString();
    }
}

// 素数?
private static bool IsPrime(int num)
{
    if (num < 2)
    {
        return false;
    }
    else if (num == 2)
    {
        return true;
    }

    if (num % 2 == 0)
    {
        return false;
    }

    for (var i = 3; i <= num / i; i += 2)
    {
        if (num % i == 0)
        {
            return false;
        }
    }
    return true;
}

 
昨日の Popup 生成部分を次のように書き換えて動かしてみます。

var popup = new Popup();
var panel = new PopupPanel() { Num  = this._popups.Count + 1 };
popup.Child = panel;

f:id:kazuakix:20140906213410j:plain,w360