2010-04-01 14 views
5

बाध्यकारी के साथ कक्षा के गुणों को संपादित करने के लिए संवाद कैसे हो सकता है, और संवाद में ठीक-रद्द हो सकता है?बाइंडिंग और ओके/रद्द करें WPF

मेरा पहला विचार था इस:

public partial class EditServerDialog : Window { 
    private NewsServer _newsServer; 

    public EditServerDialog(NewsServer newsServer) { 
     InitializeComponent(); 

     this.DataContext = (_newsServer = newsServer).Clone(); 
    } 

    private void ButtonClick(object sender, RoutedEventArgs e) 
    { 
     switch (((Button)e.OriginalSource).Content.ToString()) { 
      case "OK": 
       _newsServer = (NewsServer)this.DataContext; 
       this.Close(); 
       break; 
      case "Cancel": 
       this.Close(); 
       break; 
     } 
    } 
} 

जब स्विच में, मामला "ठीक है", DataContext सही जानकारी है, पर मूल रूप से पारित कर दिया NewsServer उदाहरण नहीं बदलता है। क्योंकि आप वास्तव में यह संशोधित नहीं किया है

+0

यदि आप बाध्यकारी सेट अप दिखाते हैं तो यह मदद कर सकता है। –

+0

बाइंडिंग का उदाहरण: {बाध्यकारी आवश्यकता प्रमाणीकरण, UpdateSourceTrigger = LostFocus, मोड = दोवे}। बाइंडिंग सही है क्योंकि यह। डेटा कॉन्टेक्स्ट में सही डेटा है। – ErikTJ

उत्तर

1

अपने NewsServer वस्तु की मूल उदाहरण नहीं बदला है। बाद ठीक बटन क्लिक किया जाता है संदर्भ निम्नानुसार होगा

newsServer = original instance 
_newsServer = original instance 
DataContext = clone of original instance 

:

newsServer = original instance 
_newsServer = clone of original instance (possibly modified) 
DataContext = clone of original instance (possibly modified) 

याद रखें कि वस्तुओं संदर्भ प्रकार अपने काम में, कर रहे हैं के बाद अपने निर्माता कहा जाता है तो आप निम्न तीन NewsServer संदर्भ हो _newsServer पर आप केवल इसके संदर्भ को अपडेट कर रहे हैं, न कि ऑब्जेक्ट का मूल्य।

NewsServer ऑब्जेक्ट को अपडेट करने की अनुमति देने के लिए, दो विकल्प हैं जो ध्यान में आते हैं, अन्य विकल्प संभवतः मौजूद हैं, पहला शायद सबसे सरल है।

  • अपने NewsServer वस्तु पर एक void Update(NewsServer source) विधि लागू _newsServer क्षेत्र के लिए नया असाइनमेंट प्रदर्शन के बजाय उस पर अद्यतन विधि कॉल और DataContext संदर्भ मूल्य प्रेषित की तो बजाय।
  • सार्वजनिक/आंतरिक संपत्ति के साथ _newsServer मान का पर्दाफाश करें। आप विभिन्न तंत्रों के माध्यम से इसका उपयोग कर सकते हैं: संपत्ति मूल्य में परिवर्तन होने पर उठाए गए किसी ईवेंट को स्पष्ट रूप से प्रतिसाद दें; संपत्ति से बंधे (उदा। इसे एक निर्भरता संपत्ति बनाएं या INotifyPropertyChanged लागू करें); या बस कॉलर को मूल्य पुनर्प्राप्त करने की उम्मीद करें यदि ShowDialog() विधि true के मान के साथ वापस आती है।

ध्यान दें कि यदि आप कॉलर पर तर्क का थोड़ा सा धक्का देते हैं, तो आपका संवाद वर्ग सरल हो सकता है। विशेष रूप से, एक दृष्टिकोण को केवल बनाए रखने के क्लोन वस्तु, एक संपत्ति के माध्यम से फोन करने वाले के संपर्क में (जैसे _newsServer क्षेत्र की पूरी तरह से छुटकारा पाने और सिर्फ DataContext का उपयोग) है। यह ऑब्जेक्ट पहले के रूप में संवाद के तत्वों के लिए बाध्य होगा। कॉलर ShowDialog() विधि से true परिणाम पर इस उदाहरण के संदर्भ को पुनर्प्राप्त करेगा।

उदाहरण के लिए:

NewsServer newsServer = ...; 
EditServerDialog editServerDialog = new EditServerDialog(newsServer); 

if (editServerDialog.ShowDialog() == true) 
{ 
    newsServer = editServerDialog.DataContext; 
} 

क्लोन उद्देश्य केवल कॉल करने वाले को नजरअंदाज कर दिया जाएगा, तो संवाद को रद्द कर दिया है, और इस तरह ShowDialog() विधि रिटर्न false। तुम बस DataContext संपत्ति के रूप में ऊपर दिखाए पुन: उपयोग कर सकता है, या आप एक अलग संपत्ति (जैसे NewsServer नाम) है कि बस DataContext संपत्ति मान देता है बना सकते हैं (अर्थात कोड थोड़ा संवाद वर्ग के सार्वजनिक इंटरफ़ेस के रूप में स्पष्ट करने के लिए)।

+0

मुझे यह कैसे करना चाहिए और अभी भी रद्द करने और/या लागू करने में सक्षम होना चाहिए? – ErikTJ

3

पुराना प्रश्न लेकिन मैं भविष्य के पाठकों के लिए इसका उत्तर दूंगा ...

आपको अपने बाइंडिंग पर UpdateSourceTrigger="Explicit" सेट करना होगा ताकि उपयोगकर्ता वास्तविक स्रोत अपडेट न करें जब तक कि उपयोगकर्ता ठीक क्लिक न करे। फिर अपने ठीक बटन हैंडलर पर आप लिख सकते हैं:

BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty); 
if (be!=null) be.UpdateSource(); 

इसके अलावा, अगर आप बाइंडिंग पुनर्स्थापित करने के लिए राज्य उपयोग प्रारंभिक

BindingExpression be = MyTextBox.GetBindingExpression(TextBox.TextProperty); 
if (be!=null) be.UpdateTarget(); 

चाहते हैं अपने संवाद जटिल है आप अपने नियंत्रण के सभी रिकर्सिवली चलने के लिए चाहते हो सकता है ।

0

यह एक पुराना सवाल है, लेकिन मैंने हाल ही में इसमें भाग लिया और पाया कि .NET 4.5 के साथ इसे संभालने का एक बेहतर तरीका है।

पहले, स्पष्ट रूप में अपने बाइंडिंग UpdateSourceTrigger निशान:

<CheckBox IsChecked="{Binding MyProperty, UpdateSourceTrigger=Explicit}"/> 

फिर, अपने ठीक बटन क्लिक करें ईवेंट हैंडलर में इस का उपयोग करें:

foreach (var be in BindingOperations.GetSourceUpdatingBindings(this)) 
{ 
    be.UpdateSource(); 
} 

GetSourceUpdatingBindings .NET 4.5 में एक नया तरीका है।

रद्द करें बटन को कुछ भी करने की आवश्यकता नहीं है, क्योंकि बाइंडिंग को स्पष्ट के रूप में चिह्नित किया गया है और जब अपडेटसोर्स कहा जाता है तो केवल "प्रतिबद्ध" होगा।

संबंधित मुद्दे