0

我正在實施名爲PhoneBox的UserControl,其中包含一個TextBox,一些自定義邏輯,並且有一個名爲PhoneNo的DependencyProperty。它將用於雙向綁定場景,LostFocusUpdateSourceTrigger。所以我寫了下面的代碼 -如何在UserControl中實現更新LostFocus源代碼的DependencyProperty?

XAML(用戶控件):

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

代碼隱藏(用戶控件):

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事件處理程序來設置proerty值(反過來更新源)的方式是否恰當?有沒有更適當的方法來做到這一點?我是這個DependencyProperty的新手,所以任何指導,建議和意見將非常感謝。

+0

你一定要明白引發LostFocus是文本框的默認?我做的是 – 2012-07-19 07:57:10

+0

。這裏的重點不是特定於「TextBox」。 – atiyar 2012-07-19 08:01:13

+0

關於綁定語法:Mode = TwoWay是TextBox.Text的默認設置,你可以沒有。 RelativeSource雖然很複雜,但是可以到這裏。您甚至可以爲您的程序集聲明一個XAML名稱空間,並使用UserControls精確類型,如{x:Type my:PhoneBox},以便更具體。通常情況下,我會使用ElementName綁定語法,但是隨後您需要爲UserControl提供一個x:Name屬性,並且如果您在其自己的XAML中設置了該屬性,並且然後使用UserControl的客戶端XAML嘗試設置x:Name在外面。 – hbarck 2012-08-28 17:44:16

回答

1

的WPF的方式來處理這種情況是有之間的用戶控件的DependencyProperty和綁定在UserControl的XAML文件中聲明的TextBox。這也是你設置LostFocus UpdateSourceTrigger(你不需要,因爲它是默認行爲)。您將在TextBox(即UserControl內)聲明Binding,因此使用UserControl的客戶端代碼可以自由設置PhoneNo屬性(來自UserControl外部)的另一個綁定。另外,如果您的CoerceValue回調只返回基值,那麼最好不要從頭開始。

這可能是什麼意思大衛最初...

0

在這種情況下,我寧願在DP元數據中使用UpdateSourceTrigger枚舉,而不使用所有冗餘方法:讓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. 

} 
+0

以及ACTUALLY保存文本的'TextBox'究竟會受到這個影響?我將如何獲取和設置文本?這不會導致'TextBox'失去焦點。你有沒有在真實應用程序代碼中嘗試它? – atiyar 2012-07-19 17:20:27

+0

它實際上取決於您的usercontrol的結構以及您計劃如何使用它。假設在你的用戶控件中有更多的子控件,並且當焦點從文本框轉到其他子控件時,你想更新屬性,在這種情況下,是的,你被鎖定在LostFocus事件選項,因爲usercontrol本身會即使文本框不再存在,仍然保持專注。但是如果你只是像你寫的文本框一樣,你不能處於userControl所關注的位置,但textBox不是,你可以使用第二個選項。 – David 2012-07-20 07:09:46

+0

「...如果你只是有你寫的文本框,你不能在userControl的位置,但文本框不是」 - 你真的有一些邏輯,現在可以看到。但情況是,無論我通過MetaData構造函數提供'UpdateSourceTrigger'還是通過XAML''PhoneNo'都不會在'LostFocus'上更新。我已經發布了整個代碼,你可以自己測試一下。 'PhoneNo'在'LostFocus'上更新的唯一情況是當我通過'txtPhone_LostFocus'事件處理程序使用'SetValue()'時。 – atiyar 2012-07-20 07:57:18

相關問題