2009-03-19 10 views
9

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

// In MeasureOverride(Size) 
m_inputWidth = 0.0; 

Size elemSize = new Size(double.PositiveInfinity, RowHeight); 
MapElementView ruler = new MapElementView(); 

// Measure inputs 
foreach (MapElementViewModel elem in m_vm.InputElements) 
{ 
    ruler.DataContext = elem; 
    ruler.Measure(elemSize); 
    m_inputWidth = Math.Max(m_inputWidth, ruler.DesiredSize.Width); 
} 

मैं वस्तु देखें तो अद्यतन करने के लिए मैं माप सकते हैं कि कैसे बड़े दृश्य ViewModel प्रदर्शित करने के लिए होने की जरूरत है के लिए बाइंडिंग हैं: यहाँ मेरी कोड है। मैं मापने के लिए एक ही दृश्य का पुन: उपयोग कर रहा हूं क्योंकि मैं डेटा वर्चुअलाइज कर रहा हूं।

क्या कोई जानता है कि डेटाकॉन्टेक्स्ट में परिवर्तन होने पर बाध्यकारी को अद्यतन करने के लिए कैसे मजबूर किया जाए?

ध्यान दें कि बाध्यकारी अंततः अद्यतन करता है।

व्यू में एक टेक्स्टब्लॉक है जो मुख्य तत्व है जो व्यूमोडेल के आधार पर आकार बदलता है। मैंने DataContext को बदलने के तुरंत बाद इस तत्व पर टेक्स्टप्रोपर्टी के लिए बाइंडिंग एक्स्प्रेशन को देखा है, लेकिन UpdateTarget() को कॉल करने से समस्या ठीक नहीं होती है और BindingExpression.DataItem शून्य प्रतीत होता है।

संपादित करें: बाइंडिंगएक्स्रेसियन की स्थिति अनुपस्थित है। चाल यह पता लगाने के लिए है कि इसे कैसे संलग्न किया जाए।

उत्तर

5

ठीक है, अगर डेटाकॉन्टेक्स्ट सेट करने के बाद, आपने डेटाबैंड प्राथमिकता पर डिस्पैचर पर एक आमंत्रण किया था, तो इसे सभी को अपडेट किया जाना चाहिए।

चूंकि यह कोड MeasureOverride विधि के अंदर निष्पादित किया जा रहा है, इसलिए आप डिस्पैचर पर कोई आमंत्रण नहीं कर सकते हैं। इसके बजाए, मैं एक ध्वज बनाउंगा जो इंगित करता है कि शासक चौड़ाई को मापा गया था, और यदि नहीं, तो उस चौड़ाई की गणना करने वाली विधि पर BeginInvoke करें। फिर, जब चौड़ाई की गणना की जाती है, तो दूसरे लेआउट पास को मजबूर करने के लिए अमान्य मेटाइज़र को कॉल करें।

प्रत्येक चौड़ाई में बदलावों में से प्रत्येक बार एक अतिरिक्त लेआउट पास की आवश्यकता होगी। टेक्स्टबॉक्स को फिर से प्राप्त करने के लिए आपको ध्वज को गलत पर रीसेट करने की आवश्यकता होगी।

private bool isRulerWidthValid = false; 

protected override Size MeasureOverride(Size available) 
{ 
    ... // other code for measuring 
    if (!isRulerWidthValid) 
    { 
     Dispatcher.BeginInvoke(new Action(CalculateRulerSize)); 
     ... // return some temporary value here 
    } 

    ... // do your normal measure logic 
} 

private void CalculateRulerSize(Size available) 
{ 
    Size elemSize = new Size(double.PositiveInfinity, RowHeight); 
    m_inputWidth = 0.0; 

    foreach (MapElementViewModel elem in m_vm.InputElements) 
    { 
     ruler.DataContext = elem; 
     ruler.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.DataBind); 
     ruler.Measure(elemSize); 
     m_inputWidth = Math.Max(m_inputWidth, ruler.DesiredSize.Width); 
    } 

    // invalidate measure again, as we now have a value for m_inputwidth 
    isRulerWidthValid = true; 
    InvalidateMeasure(); 
} 
+0

अच्छा विचार। मैं कोशिश करूँगा। –

+0

मुझे निम्न अपवाद मिला: प्रेषक प्रसंस्करण निलंबित होने पर यह ऑपरेशन निष्पादित नहीं कर सकता है। ऐसा प्रतीत होता है कि WPF लेआउट के दौरान डिस्पैचर को लॉक करता है। मैं इस कोड को MeasureOverride() में चला रहा हूँ –

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