2010-06-16 20 views
6

पर परिवर्तन नहीं करता है मैं किसी पाठ बॉक्स जिसका मूल्य एक ViewModel संपत्ति से आबद्ध है:WPF पाठ बॉक्स मूल्य OnPropertyChanged

 <TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding Mode=TwoWay, Path=RunAfter}" Style="{StaticResource TestStepTextBox}"/> 
सेट

और मिल ठीक काम कर रहे थे जब तक मैं कुछ सत्यापन जोड़ने के लिए जब मूल्य है की कोशिश की सेट:

private int _runAfter = 0; 
    public string RunAfter 
    { 
     get 
     { 
      return _runAfter.ToString(); 
     } 

     set 
     { 
      int val = int.Parse(value); 

      if (_runAfter != val) 
      { 
       if (val < _order) 
        _runAfter = val; 
       else 
       { 
        _runAfter = 0; 
        OnPropertyChanged("RunAfter"); 
       } 
      } 
     } 
    } 

हालांकि OnPropertyChanged तक पहुँच जाता है (मुझे लगता है कि dubugged है), दृश्य नहीं बदला है। मैं यह काम कैसे कर सकता हूं?

धन्यवाद, जोस Tavares

उत्तर

5

समस्या यह है कि आप Binding के लिए स्रोत अपडेट कर रहे हैं जबकि Binding आपकी संपत्ति अपडेट कर रहा है। Binding अपडेट के जवाब में PropertyChanged ईवेंट उठाते समय WPF वास्तव में आपकी संपत्ति मान की जांच नहीं करेगा।

set 
{ 
    int val = int.Parse(value); 

    if (_runAfter != val) 
    { 
     if (val < _order) 
     { 
      _runAfter = val; 
      OnPropertyChanged("RunAfter"); 
     } 
     else 
     { 
      _runAfter = 0; 
      Dispatcher.CurrentDispatcher.BeginInvoke(
       new Action<String>(OnPropertyChanged), 
       DispatcherPriority.DataBind, "RunAfter"); 
     } 
    } 
} 

अपडेट::

दूसरी बात मैंने देखा है कि आपके TextBox पर Binding डिफ़ॉल्ट उपयोग कर रहा है आप Dispatcher का उपयोग कर कि शाखा में घटना के प्रसार में देरी करने के द्वारा इस हल कर सकते हैं UpdateSourceTrigger, जो तब होता है जब TextBox फोकस खो देता है। TextBox के बाद इस पाठ के साथ फोकस खोने के बाद तक आप पाठ को 0 तक वापस नहीं देख पाएंगे। यदि आप इसे PropertyChanged पर बदलते हैं, तो आप इसे तुरंत देखेंगे।

<TextBox Name="txtRunAfter" Grid.Column="4" Text="{Binding RunAfter, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TestStepTextBox}"/> 
+0

मुझे लगता है कि समस्या का आपका मूल्यांकन सही है, लेकिन प्रेषक कॉल काम नहीं करता है। My UserControl को ElementHost का उपयोग करके WinForm एप्लिकेशन के अंदर उपयोग किया जाता है। क्या यह डिस्पैचर कॉल को प्रभावित कर सकता है? – jpsstavares

+0

ठीक है, मैंने इसका परीक्षण किया और यह ठीक काम किया (जब आप टेक्स्टबॉक्स से दूर टैब को बाध्यकारी के डिफ़ॉल्ट मोड के रूप में दूर करते हैं तो संपत्ति को अद्यतन नहीं किया जाएगा जब तक कि टेक्स्टबॉक्स फोकस न हो जाए)। मैंने बाइंडिंग पर UpdateSourceTrigger के बारे में बताने के लिए उत्तर अपडेट किया है, यदि वह व्यवहार है जिसे आप देख रहे हैं। मैं WinForms में होस्ट किए गए WPF के साथ बहुत कुछ नहीं सौदा करता, लेकिन मुझे नहीं लगता कि यह आपके संदर्भ में बाध्यकारी या डिस्पैचर को क्यों प्रभावित करेगा। –

3

कुछ बातें मैं यहाँ देखा।

जब तक आपके पास RunAfter प्रॉपर्टी को स्ट्रिंग के रूप में बेनकाब करने का कोई अनिवार्य कारण नहीं है, तो इसका कोई कारण नहीं है कि यह int नहीं हो सकता है। इससे आपको सेटटर में कास्ट बचाया जाएगा (साथ ही साथ एक अमान्य अमान्य कैस्ट अपवाद भी अगर उपयोगकर्ता फ़ील्ड में कुछ गैर-पूर्णांक में प्रवेश करता है)।

दूसरे, OnPropertyChanged() कॉल आंतरिक अगर बयान के बाहर होने चाहिए, निम्नलिखित की तरह:

if(_runAfter != val) 
{ 
    if(val < _order) 
     _runAfter = val; 
    else 
     _runAfter = 0; 
    OnPropertyChanged("RunAfter"); 
} 

के बाद से _runAfter स्थानीय सशर्त के दोनों रास्तों में अद्यतन किया जा रहा है, OnPropertyChanged() है ली गई शाखा के बावजूद बुलाया जाना चाहिए। मुझे आशा है कि आपको सही दिशा में इंगित करने में मदद मिलेगी!

+0

+1 ध्यान देने योग्य बात यह है कि आप किसी और के बाहर OnPropertyChanged बढ़ने की जरूरत के लिए। – Robaticus

+0

ठीक है, सेट को व्यू (बाध्यकारी के माध्यम से) कहा जाता है, इसलिए मैंने सोचा कि केवल ऑनप्रॉपर्टी को कॉल करना आवश्यक होगा यदि दृश्य में सेट किए गए मान से मूल्य बदला जाएगा। – jpsstavares

+0

वैसे भी, जिसने मेरी समस्या का समाधान नहीं किया ... – jpsstavares

1

मैं एक ही स्थिति थी: अन्यथा, अपनी संपत्ति जब तक आपके TextBox खो देता है ध्यान केंद्रित सेट नहीं किया जाएगा। मैंने निम्नलिखित लिखा और यह काम किया।

<TextBox Grid.Column="3" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" Text="{Binding Path=FirstName}"></TextBox>

और

public string FirstName 
    { 
     get { return _client.FirstName; } 
     set 
     { 
      if (value == _client.FirstName) 
       return; 
      else 
       _client.FirstName = value; 
      OnPropertyChanged("FirstName"); 
     } 
    } 
संबंधित मुद्दे