2011-09-09 24 views
7

मेरे सेटिंग के रूप में नीचे वर्णित है एक डिफ़ॉल्ट बटन के साथ एक संवाद पर दर्ज संपत्ति को अपडेट नहीं करता:डाटा बाध्यकारी जब दबाने

  • WPF 4 आवेदन
  • MVVM लाइट ढांचे
  • एक "जोड़ें आइटम "संवाद मोड में मुख्य विंडो के शीर्ष पर दिखाया गया है (view.ShowDialog();
  • संवाद में कई इनपुट फ़ील्ड हैं, और" सहेजें "बटन है जिसमें यह है IsDefault गुण True
  • पर सेट है
  • "सहेजें" बटन हाथ है नेतृत्व का उपयोग कर एक एक कमान
  • डेटा बाइंडिंग देखने के XAML में इनपुट के खेतों और ViewModel में इसी गुण के बीच परिभाषित किया गया है के लिए बाध्य (एक तरह से, यूआई के लिए मोड = OneWayToSource साथ ViewModel, अद्यतन करने के लिए)

समस्या यह है कि जब मैं कीबोर्ड पर एंटर दबाता हूं, तो अंतिम इनपुट फ़ील्ड में जो मान मैंने प्रदान किया है वह ViewModel की अंतर्निहित संपत्ति को धक्का नहीं दिया जाता है।

मुझे संदेह है कि इस तथ्य के साथ कुछ करने के लिए है कि विंडो बंद होने से पहले इनपुट फ़ील्ड फोकस नहीं खो गया है (और इस प्रकार सभी बाइंडिंग "भंग हो गए हैं")। तुलना के लिए, यदि मैं पर क्लिक करें "सहेजें" बटन (इसके क्लिक को विंडो पर एंटर पर संभालने की बजाय), संपत्ति में अपडेट किया गया है। इसके अलावा, अगर मैं बटन के क्लिक इवेंट में एक इवेंट हैंडलर (डरावनी! डरावनी!) जोड़ता हूं, और कोड बटन पर फोकस() कॉल करता हूं, तो सबकुछ काम करता है!

उपाय क्या हो सकता है?

मैं स्पष्ट रूप से किसी भी खिड़की बंद करने के ईवेंट प्रबंधित नहीं करना चाहते हैं, और "मैन्युअल" लापता मूल्यों लाने ... इस

कोई बेहतर सुझाव :-(पूरे MVVM अवधारणा का उल्लंघन होगा?

धन्यवाद, एलेक्स

+0

मुझे कई अन्य भाषाओं में भी इसी व्यवहार का सामना करना पड़ा है, विशेष रूप से डेल्फी (मुझे लगता है कि हेजल्सबर्ग ने यह एक विशेषता नहीं माना - अगर वह डब्ल्यूपीएफ के लिए भी जिम्मेदार था)। यदि आप किसी संख्या से जुड़ते हैं तो PropertyChanged विकल्प में समस्याएं होती हैं, क्योंकि यह "3." को सत्यापित करने का प्रयास करेगी जैसा कि आप पीआई में टाइप करते हैं और अपवाद उठाते हैं। मुझे बटन पर कोई फर्क नहीं पड़ता। फोकस() विकल्प क्योंकि यह सभी नियंत्रणों के साथ काम करेगा और भावी सबूत संवाद भी करेगा। –

उत्तर

12

डिफ़ॉल्ट रूप से, TextBox केवल इस स्रोत को सूचित करता है कि यह फ़ोकस खो जाने के बाद बदल गया है। आप इसे UpdateSourceTrigger=PropertyChanged सेट करके अपने बाध्यकारी में बदल सकते हैं। यह टेक्स्टबॉक्स को अपने स्रोत पर अपडेट अधिसूचना भेज देगा, जब यह फोकस खो देता है तो इसके टेक्स्ट को बदले में बदल दिया जाता है।

यदि आप कोई भी कुंजी दबाए जाने पर अद्यतन अधिसूचना नहीं भेजना चाहते हैं, तो आप एंटर कुंजी दबाए जाने पर स्रोत को अपडेट करने के लिए AttachedProperty बना सकते हैं।

// When set to True, Enter Key will update Source 
#region EnterUpdatesTextSource DependencyProperty 

// Property to determine if the Enter key should update the source. Default is False 
public static readonly DependencyProperty EnterUpdatesTextSourceProperty = 
    DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof (bool), 
             typeof (TextBoxHelper), 
             new PropertyMetadata(false, EnterUpdatesTextSourcePropertyChanged)); 

// Get 
public static bool GetEnterUpdatesTextSource(DependencyObject obj) 
{ 
    return (bool) obj.GetValue(EnterUpdatesTextSourceProperty); 
} 

// Set 
public static void SetEnterUpdatesTextSource(DependencyObject obj, bool value) 
{ 
    obj.SetValue(EnterUpdatesTextSourceProperty, value); 
} 

// Changed Event - Attach PreviewKeyDown handler 
private static void EnterUpdatesTextSourcePropertyChanged(DependencyObject obj, 
                  DependencyPropertyChangedEventArgs e) 
{ 
    var sender = obj as UIElement; 
    if (obj != null) 
    { 
     if ((bool) e.NewValue) 
     { 
      sender.PreviewKeyDown += OnPreviewKeyDownUpdateSourceIfEnter; 
     } 
     else 
     { 
      sender.PreviewKeyDown -= OnPreviewKeyDownUpdateSourceIfEnter; 
     } 
    } 
} 

// If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property 
private static void OnPreviewKeyDownUpdateSourceIfEnter(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Enter) 
    { 
     if (GetEnterUpdatesTextSource((DependencyObject) sender)) 
     { 
      var obj = sender as UIElement; 
      BindingExpression textBinding = BindingOperations.GetBindingExpression(
       obj, TextBox.TextProperty); 

      if (textBinding != null) 
       textBinding.UpdateSource(); 
     } 
    } 
} 

#endregion //EnterUpdatesTextSource DependencyProperty 
3

इस प्रयास करें।

{संपत्ति बाइंडिंग, UpdateSourceTrigger = PropertyChanged, मोड = OneWayToSource}

-3

यह बस एक WPF बग है:

यहाँ AttachedProperty है कि मैं इस तरह की स्थितियों के लिए उपयोग करते हैं। (डिजाइन या कार्यान्वयन, मुझे नहीं पता।) खोए गए फोकस पर टेक्स्टबॉक्स अपडेट ज्यादातर मामलों में अपेक्षित व्यवहार है और डिफ़ॉल्ट बटन को संवाद में काम करना चाहिए।

कामकाज के लिए, मुझे लगता है कि टेक्स्टबॉक्स के साथ गुस्से में यह गलत दिशा है। बेहतर समाधान डिफ़ॉल्ट बटन पर ध्यान केंद्रित करने के लिए है।

0

एक साधारण चाल नियंत्रण से दूर ध्यान केंद्रित करने के लिए है। बटन पर ही। आप बटन का हैंडलर क्लिक में ऐसा कर सकते हैं, के रूप में यह बाध्य आदेश से पहले निष्पादित किया जाएगा:

public MyView() 
    { 
     InitializeComponent(); 

     _button.Click += delegate 
     { 
      _button.Focus(); 
     }; 
    } 

आप अपने दृश्य में पीछे कोड पसंद नहीं है, तो आप भी एक व्यवहार में ऐसा कर सकते हैं आप अपने बटन में जोड़ें।

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