0

私はUserControl、単一TextBoxのカスタムロジックを含み、PhoneNoというDependencyPropertyを持つ呼び出されたPhoneBoxを実装しようとしていました。LostFocusこれは、 forを使用した双方向バインディングシナリオで使用される予定でしたUpdateSourceTrigger。だから私は次のコードを書きました-

XAML(UserControl):

<StackPanel>
    <TextBox Name="txtPhone" MinWidth="120" MinHeight="23" LostFocus="txtPhone_LostFocus" GotFocus="txtPhone_GotFocus"/>
</StackPanel>  

コードビハインド(UserControl):

public partial class PhoneBox : UserControl
{
    //Some Code

    static PhoneBox()
    {
        FrameworkPropertyMetadata phoneNoMetadata =
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnPhoneNoChanged),
                                          new CoerceValueCallback(CoercePhoneNoValue));
        PhoneNoProperty = DependencyProperty.Register("PhoneNo", typeof (string), typeof (PhoneBox),
                                                       phoneNoMetadata,
                                                       new ValidateValueCallback(ValidatePhoneNoValue));
    }

    public readonly static DependencyProperty PhoneNoProperty;
    public string PhoneNo
    {
        get { return (string)GetValue(PhoneNoProperty); }
        set { SetValue(PhoneNoProperty, value); }
    }

    private static void OnPhoneNoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        PhoneBox phoneBox = (PhoneBox)d;
        string newValue = (string)e.NewValue;

        phoneBox.txtPhone.Text = newValue;
    }

    private static object CoercePhoneNoValue(DependencyObject d, object basevalue)
    {
        return basevalue;
    }

    private static bool ValidatePhoneNoValue(object value)
    {
        return true;
    }

    private void txtPhone_LostFocus(object sender, RoutedEventArgs e)
    {
        this.SetValue(PhoneNoProperty, this.txtPhone.Text);
    }

    private void txtPhone_GotFocus(object sender, RoutedEventArgs e)
    {
        if (!String.IsNullOrEmpty(txtPhone.Text))
            this.txtPhone.Text = this.FilterText(txtPhone.Text);
    }

    private string FilterText(string text)
    {
        //Some cutom logic
    }

    //Some more Code
}  

XAML(コンシューマー):

<pbc:PhoneBox PhoneNo="{Binding Path=User.Phone, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>  

できます。しかし、私の質問は、txtPhone_LostFocusイベントハンドラーを使用してプロパティ値を設定する(そしてソースを更新する)方法は適切ですか?これを行うためのより適切な方法はありますか?私はこのDependencyPropertyことの初心者なので、ガイド、提案、コメントはありがたいことに感謝します。

4

2 に答える 2

1

この状況を処理するWPFの方法は、UserControlとUserControlのXAMLファイルで宣言されたものDependencyPropertyとの間にバインディングを作成することです。TextBoxこれは、LostFocus UpdateSourceTrigger(デフォルトの動作であるため、設定する必要はありません)を設定する場所でもあります。(つまり、UserControl内で) Bindingを宣言するTextBoxので、UserControlを使用するクライアントコードは、(UserControlの外部から)PhoneNoプロパティに別のバインディングを自由に設定できます。また、CoerceValueコールバックが基本値のみを返す場合は、最初から基本値を返さない方がよいでしょう。

これは、Davidが最初に意味したことかもしれません...

于 2012-08-25T07:25:06.713 に答える
0

この場合、私は実際にEventHandlerUpdateSourceTriggerよりもDPメタデータの列挙を使用しLostFocus、すべての冗長なメソッドを削除したいと思います。可能であれば、WPFにそれらのことを実行させることをお勧めします。もっと早く。

さらに、この場合、個人的には、lostFocusメソッドよりもメタデータを読み取る方がはるかに簡単だと思います。しかし、これは私が推測する好みの問題です。

編集:いいえいいえ、私はあなたが何を意味するのか理解しました、しかし私は私の答えで自分自身を明確にしなかったかもしれません。これが私が大まかに行うことです(あなたにヒントを与えるために、あなたの場合にはいくつかの調整が必要になります):

public partial class PhoneBox : UserControl
{
    public static readonly DependencyProperty PhoneNoProperty = DependencyProperty.Register(
        "PhoneNo",
        typeof (string),
        typeof (PhoneBox),
        new UIPropertyMetadata(UpdateSourceTrigger.LostFocus),
        new ValidateValueCallback(ValidatePhoneNoValue));

    public string PhoneNo
    {
        get { return (string)GetValue(PhoneNoProperty); }
        set { SetValue(PhoneNoProperty, value); }
    }

// ... your code here.

}
于 2012-07-19T07:52:44.173 に答える