2012-04-09 14 views
6

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

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
     <ComboBox Height="25" Width="120" SelectedValue="{Binding SelectedValue}" SelectedValuePath="Key" ItemsSource="{Binding PossibleValues}" DisplayMemberPath="Value"/> 
    </Grid> 
</Window> 

यहाँ और मॉडल है:

समस्या समझने के लिए, यहाँ एक सरल XAML है

using System.Collections.Generic; 
using System.Windows; 
using System.ComponentModel; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     int m_selectedValue = 2; 
     Dictionary<int, string> m_possibleValues = new Dictionary<int, string>() { { 1, "one" }, { 2, "two" }, { 3, "three" }, {4,"four"} }; 

     public int SelectedValue 
     { 
     get { return m_selectedValue; } 
     set 
     { 
      if (value == 3) 
      { 
       m_selectedValue = 1; 
      } 
      else 
      { 
       m_selectedValue = value; 
      } 
      PropertyChanged(this, new PropertyChangedEventArgs("SelectedValue")); 
     } 
     } 
     public Dictionary<int, string> PossibleValues 
     { 
     get { return m_possibleValues; } 
     set { m_possibleValues = value; } 
     } 


     public MainWindow() 
     { 
     InitializeComponent(); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

मैं उम्मीद व्यवहार इस प्रकार हो:

  1. प्रारंभ में, दो को चुना गया है
  2. "एक" चुनें -> कॉम्बोबॉक्स डिस्प्ला वाईएस "एक"
  3. का चयन करें "दो" -> ComboBox प्रदर्शित करता है "दो"
  4. चुनें "तीन" -> ComboBox प्रदर्शित करता है "एक"
  5. का चयन करें "चार" -> ComboBox प्रदर्शित करता है "चार"

हालांकि, # 4 में, "तीन" प्रदर्शित होता है। क्यूं कर? मॉडल में मान 1 ("एक") में बदल दिया गया था, लेकिन दृश्य अभी भी 3 ("तीन") प्रदर्शित करता है।

मुझे चयन चयन किए गए ईवेंट हैंडलर में बाध्यकारी लक्ष्य को स्पष्ट रूप से अपडेट करके एक समाधान मिला है, लेकिन यह गलत लगता है। क्या यह हासिल करने का कोई और तरीका है?

+0

क्या कॉम्बोबॉक्स मॉडल की वर्तमान स्थिति प्रदर्शित नहीं करना चाहिए? यह सहज नहीं हो सकता है, लेकिन प्रदर्शित करने के लिए यह सही बात है। यह वास्तव में एक सरलीकृत उदाहरण है। वास्तविक उपयोग केस थोड़ा अधिक जटिल है, लेकिन यह एक ही मुद्दे पर उबलता है – Rado

+0

क्या आपने चयनित वैल्यू को स्पष्ट रूप से दो-तरफा बनाने का प्रयास किया है? {बाध्यकारी पथ = चयनित वैल्यू, मोड = दोवे} –

+0

@ जैकोबप्रॉफिट मोड डिफ़ॉल्ट रूप से दोवे है, लेकिन मैंने इसे स्पष्ट रूप से सेट करने की कोशिश की और समस्या बनी रहती है। – Rado

उत्तर

5

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

सिस्टम मानता है कि सेटर उस मूल्य को नहीं बदलेगा जो इसे पारित किया गया था। यहां कामकाज सरल है: Dispatcher.BeginInvoke() का उपयोग करें या जिस व्यवहार को आप ढूंढ रहे हैं उसे प्राप्त करने के लिए अपने बाध्यकारी पर IsAsync=True सेट करें। हालांकि, मैं व्यक्तिगत रूप से को हतोत्साहित करता हूं। न केवल इसलिए कि यह समय से संबंधित नई समस्याओं का पूरा समूह पेश करता है, लेकिन मुख्य रूप से क्योंकि यह किसी समस्या के लिए एक समाधान है जो पहले स्थान पर मौजूद नहीं होना चाहिए।

बस यह मत करें। यह न केवल डब्ल्यूपीएफ के लिए आवेदन कर रहा है: एक सेटटर को बदलने वाला कुछ भी उम्मीद कर सकता है कि जिस कीमत को अभी सेट किया गया है वह सही ढंग से सेट किया गया है, कोई अपवाद नहीं फेंक दिया गया है। सेटर के अंदर मूल्य बदलना अंतर्ज्ञानी है और बाद में आपको काट सकता है। इसके अलावा, यह आपके चयन के अनदेखा को combobox देखने के लिए आपके एप्लिकेशन के उपयोगकर्ता के लिए वास्तव में परेशान हो सकता है।

यदि आपको मूल्य पारित करना पसंद नहीं है, तो अपवाद फेंक दें और Binding.ValidatesOnExceptions का उपयोग WPF को यह बताने के लिए करें कि इसकी अपेक्षा की जाती है।यदि आप नहीं चाहते कि उपयोगकर्ता इस मान का चयन करे, तो उसे सूची में पहले स्थान पर न रखें। यदि आइटम अन्य व्यावसायिक नियमों के कारण सशर्त रूप से उपलब्ध नहीं होना चाहिए, तो सूची को गतिशील रूप से फ़िल्टर करें या ट्रिगर लागू करें।

+0

'IsAsync = True' काम करता है। विवरण पढ़ना, मुझे यकीन नहीं है कि ऐसा क्यों होता है क्योंकि इसका अर्थ यह नहीं है लेकिन यह करता है :)। आपने बताया कि आप इस कार्यान्वयन को हतोत्साहित करते हैं। कोई सुझाव जो मैं इसके बजाय कर सकता हूं? वास्तविक उपयोग केस यह है: मेरे पास पूर्वनिर्धारित मूल्य प्रोफाइल हैं जिन्हें मुझे अनुमान लगाने का प्रयास करना है। यह मानचित्र वास्तव में एक combobox प्रतिमान के साथ अच्छी तरह से है क्योंकि उपयोगकर्ता को पूर्वनिर्धारित मानों में से एक का चयन करना चाहिए। हालांकि, कुछ ऐसे मामले हैं जब मैं चयनित मूल्य तक नहीं पहुंच पा रहा हूं, इसलिए उपयोगकर्ता को गुमराह करने के लिए, मैं मान को "बीच में" मान में बदलना चाहता हूं। – Rado

+0

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

+1

मैं असहमत हूं। "सेटर" संपत्ति रखने का पूरा बिंदु बैकिंग फ़ील्ड की रक्षा करना है (जिसे सार्वजनिक किया जा सकता है)। संपत्ति मूल्य पर चेक और सत्यापन कर रही है और यह सुनिश्चित करना चाहिए कि यह मान्य है। यदि ऐसा नहीं है, तो अपवाद फेंकना हमेशा व्यावहारिक समाधान नहीं होता है। –

2

SelectedValue और/या SelectedItemComboBox नियंत्रण के बाध्यकारी होने पर मुझे नियंत्रण की उचित अद्यतन के साथ लगातार समस्याएं आई हैं।

इसे हल करने के लिए, मुझे इसके बजाय SelectedIndex संपत्ति से जुड़ना पड़ा। मेरे व्यूमोडेल में 'इंडेक्स' प्रॉपर्टी से निपटने में और अधिक परेशानी थी, लेकिन इसने ComboBox अद्यतन करने के साथ समस्या हल नहीं की।

+0

मैंने वास्तव में एक ही परिणाम के साथ सभी चयनित वैल्यू, चयनित इटैम और चयनित इंडेक्स को आजमाया। – Rado

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