2009-10-30 68 views
7

我有我使用的是DataTemplate內的用戶控件,這UserControl包含被綁定我UserControl價值財產(聲明爲DependencyProperty)一個TextBox。在數據模板中,我將這個屬性與我的實際屬性說名稱(也是DependencyProperty)。它正常工作,我分配一個值來名稱的特性,同時加載和我TextBox顯示它,我改變從TextBox的價值,同時也更新我的名稱屬性。 現在,當我在依賴項屬性中添加PropertyChangedEventHandler時,問題出現了,我檢查該值是否有效,如果有效,則不執行任何操作,如果無效,則執行任何操作。在價值無效的情況下,當我將其分配給舊值時,屬性更新但它不顯示更新值在我的TextBoxUserControl中。誰能告訴我爲什麼?WPF:文本框的文本沒有更新

XAML的UserControl

<UserControl x:Name="usercontrol"> 
    <StackPanel> 
     <TextBlock ......./> 
     <TextBox Binding={Binding ElementName=usercontrol, Path=Value, Mode=TwoWay}/> 
    </StackPanel> 
</UserControl> 

在後面代碼是DependencyProperty

我在我的DataTemplate使用此:

<HierarchicalDataTemplate DataType="{x:Type myLib:myClass}" ItemsSource="{Binding Children}"> 
    <Expander Header="{Binding}"> 
     <WrapPanel> 
      <edproperty:TextPropertyEditor Caption="Name" Value="{Binding Name, Mode=TwoWay}"/> 
      <edproperty:TextPropertyEditor .................../> 
      <edproperty:TextPropertyEditor .................../> 
      <edproperty:TextPropertyEditor ...................../> 
     </WrapPanel> 
    </Expander> 
</HierarchicalDataTemplate> 

此模板我在中使用。裏面TreeView我進入這將更新我UserControl價值屬性TextBox值,這反過來又更新名稱的myClass我分配財產PropertyChangedCallback名稱屬性,myClass,執行一些驗證和重新分配OldValue如果驗證失敗。它反過來更新價值財產也,但我仍然看到TextBox具有相同的價值,我剛纔進入而不是更新的一個。

​​
+2

沒有看到您的代碼,這將是一個難以適當評論。你可以發佈你的代碼嗎? – 2009-10-30 10:54:48

+0

它太多了,不能發佈。你可以問你是否想要更多的解釋。 – viky 2009-10-30 13:27:59

+2

不,你可以寫最小的代碼片來重現......否則,我們會猜測,而不是回答。沒有人喜歡不確定性。特別是程序員.. – Anvaka 2009-10-30 14:49:42

回答

0

它看起來像你破壞了綁定時你直接從代碼中設置屬性值的後面。

您不應該那樣修改屬性。使用value coercion mechanism並驗證Coerce值回調中的輸入。

+0

我用這種方式也是同樣的問題,我的文本框的值不會更新。 – viky 2009-10-30 13:26:55

+0

我已經更新了我的問題,你能告訴我什麼嗎? 對不起延遲 – viky 2009-11-10 12:52:29

0

阿努拉格,

有很多假設,我要在這裏做的,但我給它一個鏡頭。

你可能有這樣的事情......

// ... 
public static string GetValue(Dependency obj) 
{ 
    // ... 
} 

// ... 
public static void SetValue(DependencyObject obj, string value) 
{ 
    // ... 
} 

// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty ValueProperty = 
    DependencyProperty.RegisterAttached("Value", typeof(string), typeof(MyCustomControl), new UIPropertyMetadata(OnValuePropertyChanged)); 

public static void OnValuePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
{ 
    string newValue = e.NewValue as string; 

    // You validate your value here, 
    // Then if fails, revert to old value. 
    if(!SomeCondtion(newValue)) SetValue(obj,e.OldValue as string); 

} 

這絕對不是驗證數據的最佳方式。還有其他更有效的方法可以給你更多的靈活性。

  1. 在您的TexBox上應用ValidationRule。這是我的第一個建議,因爲它可以讓你控制驗證失敗時顯示錯誤。如果您經過簡單驗證,請查看我的article
  2. 偵聽TextBox.TextChanged事件。這很麻煩,而且在大多數黑客中都不能重複使用。
  3. 請勿使用DependecyPropertyChanged回調方法。使用已註冊的字符串屬性並在您的設置器中應用邏輯,例如

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(UserControlWithTextBox)); 
    
    
    private string _oldValue; 
    public string Value 
    { 
        get { return GetValue(ValueProperty) as string; } 
        set 
        { 
         // Check if the value passes your validation logic 
         if(SomeCondtion(value)) 
         { 
          // If yes, then set the value, and record down the old value. 
          SetValue(ValueProperty, value); 
          _oldValue = value; 
         } 
         else 
         { 
          // Else logic fails, set the value to old value. 
          SetValue(ValueProperty, _oldValue); 
         } 
         // Implement INotifyPropertyChanged to update the TextBox. 
         if(PropertyChanged != null) 
          PropertyChanged(this, new PropertyChangedEventArgs("Value")); 
        } 
    } 
    

再次,你可以從我的回答看,你仍然可以顯示你的問題代碼,以幫助別人回答你的問題,無論您的解決方案可能多麼複雜(如果你想有一個很好的答案,你需要努力提出一個好問題)。我的答案可能不適合你,但也許它可能會給你一些「谷歌搜索」的方向。希望能幫助到你。

+0

我已經更新了我的問題,對不起延遲 爲什麼它發生在我的文本框? – viky 2009-11-10 12:53:30

+0

當WPF通過綁定或setter或通過其他此類機制更新屬性時,不會在您的示例中添加到setter的驗證。建議在使用依賴項屬性時不要在訪問器或增變器中放置任何東西。 – jpierson 2010-12-07 22:37:52

1

我知道這個問題是關於文本框但RichTextBox中你可以使用UpdateLayout請()。

rtb.AppendText("Text"); 
rtb.ScrollToEnd(); 
rtb.UpdateLayout();