2009-10-30 14 views
7

मैं एक उपयोगकर्ता नियंत्रण है कि मैं एक DataTemplate अंदर का उपयोग कर रहा है, यह UserControl एक TextBox जो मेरे UserControl की मूल्य संपत्ति (एक DependencyProperty के रूप में घोषित) के साथ आबद्ध होता है। डेटा टेम्पलेट में मैं अपनी वास्तविक संपत्ति के साथ वैल्यू संपत्ति को बांधता हूं नाम (एक DependencyProperty भी)। यह ठीक से काम करता है, मैं नाम संपत्ति लोड करने के दौरान TextBox प्रदर्शित करता हूं, मैं TextBox से मान बदलता हूं और यह नाम संपत्ति को भी अपडेट करता है। अब समस्या तब आती है जब मैं निर्भरता संपत्ति में PropertyChangedEventHandler जोड़ता हूं, यदि यह वैध है तो मैं मान की जांच करता हूं, वैध होने पर मान्य नहीं है और मान्य नहीं होने पर पुराना मान असाइन करता हूं। मान मान्य होने पर, जब मैं इसे पुराना मान, संपत्ति अद्यतन असाइन करता हूं लेकिन यह UserControl के TextBox में अद्यतन मान प्रदर्शित नहीं कर रहा है। क्या कोई मुझे बता सकता है क्यों?WPF: पाठ बॉक्स पाठ को अद्यतन करने नहीं है

XAML की मेरी UserControl:

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

इस टेम्पलेट मैं हूं:

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

मूल्य पीछे कोड में एक DependencyProperty

मैं अपने DataTemplate में इस का उपयोग कर रहा हैमें उपयोग करना। TreeView अंदर मैं TextBox जो मेरे UserControl की मूल्य संपत्ति अद्यतन करता है में मान दर्ज करें, कि बारी अद्यतन नाम myClass मैं बताए हूँ की संपत्ति में एक PropertyChangedCallback मेरी नाम myClass में संपत्ति, कुछ मान्यता प्रदर्शन और OldValue फिर नियत करने के लिए अगर सत्यापन विफल रहता है। यह बदले में वैल्यू संपत्ति भी अपडेट करता है, लेकिन मुझे अभी भी यह देख रहा है कि TextBox का वही मान है जो मैंने पहले अपडेट नहीं किया था।

public string Name 
    { 
     get 
     { 
      return (string)GetValue(NameProperty); 
     } 
     set 
     { 
      SetValue(NameProperty, value); 
     } 
    } 

    // Using a DependencyProperty as the backing store for Name. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty NameProperty = 
     DependencyProperty.Register("Name", typeof(string), typeof(myClass), new UIPropertyMetadata(null, OnNameChanged)); 

    protected static void OnNameChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     if(checkRequired && !IsValid(e.NewValue.ToString())) 
     { 
      checkRequired=false; 
      (sender as myClass).Name = args.OldValue.ToString(); 
     } 
    } 

    private static bool IsValid(string name) 
    { 
     .............some logic here 
    } 
+2

अपना कोड देखे बिना, यह सही तरीके से टिप्पणी करने के लिए एक कठिन होगा। क्या आप अपना कोड कृपया पोस्ट कर सकते हैं? –

+0

यह बहुत अधिक है, इसे पोस्ट नहीं किया जा सकता है। आप पूछ सकते हैं कि क्या आप अधिक स्पष्टीकरण चाहते हैं। – viky

+2

नहीं, आप पुन: उत्पन्न करने के लिए न्यूनतम कोड टुकड़ा लिख ​​सकते हैं ... अन्यथा, हम अनुमान लगाएंगे, जवाब नहीं देंगे। कोई भी अनिश्चितता पसंद नहीं करता है। विशेष रूप से प्रोग्रामर .. – Anvaka

उत्तर

7

चारों ओर देख के दिनों और खोज का एक बहुत बाद मैं मेरी समस्या

का समाधान सभी सत्यापन किया और पुराने मान निर्दिष्ट और निर्भरता संपत्ति को अद्यतन करने, मैं कैलोरी को UpdateTarget() विधि की जरूरत के बाद पाया है, अद्यतन करने के लिए मेरे टेक्स्टबॉक्स में मूल्य।

यह वही समाधान मैं जानता हूँ कि इस सवाल का पाठ बॉक्स के बारे में था बेहतर

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/c404360c-8e31-4a85-9762-0324ed8812ef/

+0

धन्यवाद! तुमने मेरी जान बचाई!! –

0

ऐसा लगता है कि जब आप संपत्ति के मूल्य को सीधे कोड से सेट करते हैं तो आप बाध्यकारी तोड़ रहे हैं।

आपको इस तरह से संपत्ति को संशोधित नहीं करना चाहिए। value coercion mechanism का उपयोग करें और Coerce मान कॉलबैक में इनपुट मान्य करें।

+0

मैंने इस तरह से भी उपयोग किया लेकिन फिर भी एक ही समस्या है, मेरे टेक्स्टबॉक्स का मूल्य अपडेट नहीं होता है। – viky

+0

मैंने अपना प्रश्न अपडेट किया है, क्या आप मुझे कुछ सुझाव दे सकते हैं? देरी के लिए खेद है – viky

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 पर एक सत्यापन नियम लागू करें।यह मेरी पहली सिफारिश है क्योंकि यह सत्यापन विफल होने पर त्रुटि प्रदर्शित करने पर आपको नियंत्रण देगा। यदि आप एक साधारण सत्यापन के बाद हैं, तो मेरे article देखें।
  2. टेक्स्टबॉक्स के लिए सुनो .extChanged घटना। यह बोझिल है और अधिकांश हैक किए जाने पर पुनः उपयोग करने योग्य नहीं है।
  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

+0

आपके उदाहरण में सेटर में जोड़ा गया सत्यापन तब नहीं होगा जब WPF बाध्यकारी या एक सेटटर या अन्य ऐसे तंत्रों के माध्यम से संपत्ति को अद्यतन करता है। निर्भरता गुणों का उपयोग करते समय कभी भी अपने एक्सेसर्स या म्यूटेटर में कुछ भी डालने की अनुशंसा नहीं की जाती है। – jpierson

1

बताते है, लेकिन RichTextBox के लिए आप UpdateLayout का प्रयोग करेंगे()।

rtb.AppendText("Text"); 
rtb.ScrollToEnd(); 
rtb.UpdateLayout(); 
संबंधित मुद्दे