2011-06-15 7 views
5

मुझे एक कनवर्टर के साथ एक डेटा बाध्यकारी स्थापित किया गया है जो एक अजीब XML स्रोत को एक डिस्प्ले- और संपादन-आंतरिक वर्गों के सुविधाजनक पेड़ को बदलने के लिए है। एक्सएमएल स्रोत से पढ़ने के लिए सबकुछ बढ़िया काम करता है, लेकिन मुझे एक समय का शैतान है जो आंतरिक वर्गों में एक्सएमएल स्रोत पर प्रचार करने के लिए बदलाव करने की कोशिश कर रहा है।कनवर्टर के साथ दो-तरफा डेटा बाध्यकारी स्रोत अपडेट नहीं करता

यहाँ उपयोग साइट के लिए XAML है:

 <local:SampleConverter x:Key="SampleConverter" /> 
     <Expander Header="Sample" > 
      <local:SampleControl 
       Sample="{Binding Path=XmlSource, 
           Converter={StaticResource SampleConverter}, 
           Mode=TwoWay}" /> 
     </Expander> 

XmlSource एक CLR पढ़ने-लिखने की संपत्ति (नहीं DependencyProperty) बाध्य वस्तु माता पिता डेटा की है। यह एक एक्सएसडी से उत्पन्न एक .NET प्रकार है।

नमूना कनवर्टर IValueConverter लागू करता है। Convert विधि को गैर-शून्य डेटा कहा जाता है और लौटाता है, लेकिन ConvertBack विधि कभी नहीं कहा जाता है।

नमूना नियंत्रण एक उपयोगकर्ता नियंत्रण है जो नमूना डेटा पेड़ के साथ यूआई इंटरैक्शन को समाहित करता है। यह XAML इस तरह दिखता है:

<UserControl x:Class="SampleControl"> 
    [... other stuff ...] 

    <UserControl.Content> 
     <Binding Path="Sample" RelativeSource="{RelativeSource Mode=Self}" Mode="TwoWay" TargetNullValue="{StaticResource EmptySampleText}" /> 
    </UserControl.Content> 

    <UserControl.ContentTemplateSelector> 
     <local:BoxedItemTemplateSelector /> 
    </UserControl.ContentTemplateSelector> 
</UserControl> 

नमूना संपत्ति के पीछे SampleControl कोड में एक DependencyProperty है:

public static readonly DependencyProperty SampleProperty = 
    DependencyProperty.Register("Sample", typeof(SampleType), typeof(SampleControl), new PropertyMetadata(new PropertyChangedCallback(OnSampleChanged))); 

public SampleType Sample 
{ 
    get { return (SampleType)GetValue(SampleProperty); } 
    set { SetValue(SampleProperty, value); } 
} 

private static void OnSampleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    if (e.NewValue != null) 
    { 
     ((INotifyPropertyChanged)e.NewValue).PropertyChanged += ((SampleControl)d).MyPropertyChanged; 
    } 
    else if (e.OldValue != null) 
    { 
     ((INotifyPropertyChanged)e.OldValue).PropertyChanged -= ((SampleControl)d).MyPropertyChanged; 
    } 
} 

private void MyPropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    ; // breakpoint here shows change notices are happening 
} 

कि XmlSource INotifyPropertyChanged लागू करने के लिए बदल जाती है आंतरिक वर्गों, और परिवर्तन सूचनाएं भेज रहे हैं पेड़, जैसा कि ऊपर MyChroperty में एक ब्रेकपॉइंट द्वारा इंगित किया गया है।

तो यदि डेटा रिपोर्ट कर रहा है कि यह बदल गया है, तो डब्ल्यूपीएफ मेरे कनवर्टर की कनवर्टबैक विधि क्यों नहीं बुला रहा है?

+0

संपत्ति बदलाव के लिए आपका कोड नमूना केवल इंगित करता है कि नमूना के गुणों को बदल रहे हैं, नमूना ही नहीं। – Ragepotato

+0

@Ragepotato: आप कह रहे हैं कि डेटा केवल बाध्यकारी अगर एक नया उदाहरण नमूना संपत्ति को सौंपा गया है काम करता है, लेकिन नमूना संपत्ति से जाना जाता मौजूदा उदाहरण के गुणों बदल रहे हैं नहीं तो और INotifyPropertyChanged के माध्यम से अपने परिवर्तन का संकेत? – dthorpe

+0

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

उत्तर

2

इतने पर यहाँ कई इसी तरह के सवाल से संकेत और लगभग जवाब के साथ, मैं एक काम कर समाधान है कि बंधन को बरकरार रखता है है। आप रणनीतिक रूप से रखे गए ईवेंट में स्रोत को अपडेट करने के लिए बाध्यकारी रूप से बाध्यकारी कर सकते हैं, जैसे लॉस्टफोकस:

private void mycontrol_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (mycontrol.IsModified) 
    { 
     var binding = mycontrol.GetBindingExpression(MyControl.SampleProperty); 
     binding.UpdateSource(); 
    } 
} 
0

XmlSource एक CLR पढ़ने-लिखने की संपत्ति (नहीं DependencyProperty) माता-पिता डेटा बाध्य वस्तु की है। यह एक एक्सएसडी से उत्पन्न एक .NET प्रकार है।

मुझे विश्वास है कि यह आपकी समस्या है। एक मूल सीएलआर संपत्ति अधिसूचित नहीं होगी, और इस प्रकार दो-तरफा डाटाबेसिंग में भाग लेने में असमर्थ है। मेरा अनुमान होगा कि आप एक बार बाध्यकारी हो रहे हैं? क्या आपके आउटपुट विंडो में कोई डाटाबेसिंग त्रुटियां हैं?

आप एक आवरण है कि XmlSource संपत्ति के वर्ग में शामिल है बनाने की कोशिश कर सकते, (यह नहीं निर्भरता संपत्ति होने की जरूरत नहीं है) उस वर्ग INotifyPropertyChanged को लागू करना है, और एक सूचित संपत्ति के रूप में XmlSource बेनकाब।

इसके अलावा

, इस टिप्पणी के बारे में:

आप कह रहे हैं कि केवल काम करता है बाध्यकारी अगर एक नया उदाहरण नमूना संपत्ति को असाइन किया गया डेटा, लेकिन अगर मौजूदा उदाहरण की गुणों के द्वारा नहीं भेजे गए नमूना संपत्ति बदल गई है और INotifyPropertyChanged के माध्यम से उनके परिवर्तनों को सिग्नल करें? जब संपत्ति ही है, बदल जाता है जब नहीं बच्चों या अन्य गुणों को बदलने INotifyPropertyChanged की

नमूना implementions आमतौर पर अधिसूचना घटित होता है। हालांकि, आप किसी भी समय किसी भी संपत्ति पर अधिसूचना घटना को पूरी तरह से आग लगा सकते हैं।उदाहरण के लिए, आपके पास "पूर्ण नाम" संपत्ति हो सकती है जो "प्रथम नाम" या "अंतिम नाम" परिवर्तन को सूचित करती है।

यदि उपरोक्त उपयोगी नहीं है, मैं अपने कोड का एक सा अधिक पोस्टिंग सुझाव है - हो सकता है कि आप क्या काम कर पाने की कोशिश कर रहे का एक सरलीकृत रेप्रो।

संपादित करें:

मुझे लगता है कि मैं अपने प्रश्न को गलत समझा। मुझे लगता है कि समस्या यह है कि आपने अपनी टिप्पणियों में क्या बताया - यह एक संदर्भ प्रकार है। अपने OnSampleChanged में यह कोशिश कर रहा लायक हो सकता है:

private static void OnSampleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var oldValue = Sample; 
    Sample = new SampleType(); 
    Sample = oldValue; 
} 

मुझे लगता है कि यह है कि कुछ लक्ष्य की ओर बदल पहचान करने के लिए बाध्यकारी प्रणाली बाध्य करेगा।

+0

XmlSource CLR प्रॉपर्टी पहले से ही INotifyProperty लागू किया गया है।इसके अलावा, कनवर्टर के कन्वर्टबैक को XmlSource प्रॉपर्टी को असाइन करने के लिए मान प्राप्त करने के लिए पहले कॉल करने की आवश्यकता होगी, और कन्वर्टबैक को नहीं कहा जा रहा है। – dthorpe

0

इसी तरह की समस्या थी।

इसके बजाय दो तरह से बाध्यकारी मैं एक तरह से इस्तेमाल किया की

, और एक कनवर्टर: समाधान निम्नलिखित था। कन्वर्टर ऑब्जेक्ट (आपके मामले में, xmlsource प्रॉपर्टी का मूल ऑब्जेक्ट) को एक दृश्य मॉडल में परिवर्तित करता है (encapsulates), और नियंत्रण इसके लिए बाध्य करता है।

ViewModel एक प्रॉक्सी तरह काम करता है, वस्तु के लिए एक संदर्भ रखती है यह गुण है प्रबंधन करता है, और निश्चित रूप से लागू करता है INotifyPropertyChanged। इस मामले में आपको कन्वर्टबैक विधि को कॉल करने की आवश्यकता नहीं है, क्योंकि संचालन दृश्य मॉडल के माध्यम से उचित उदाहरण पर किया जाता है।

तो तुम एक साफ दृश्य है, तो आप xaml.cs में किसी भी कोड की जरूरत नहीं है