2012-04-15 13 views
6

के बीच डेटा बदल गया है मेरे पास एक सरणी है, डेटा को टीवीर्टुअलस्ट्रिंगट्री पर प्रदर्शित किया जाएगा। यह सरणी थ्रेड-सुरक्षित और लॉक करने योग्य है। और एक और धागे से उगाया।टीवीर्टुअलस्टिंगट्री: ऑनमेइटर इटैम इवेंट और ऑनजीटटेक्स्ट इवेंट

मेरी समस्या यह है कि, जब VST नोड की ऊंचाई मापने के लिए OnMeasureItem ईवेंट निष्पादित करता है, तो माप के लिए उपयोग किया जाने वाला डेटा बदल सकता है जब यह ऑनगेटटेक्स्ट ईवेंट के साथ प्रिंटिंग डेटा के बिंदु पर आता है।

मैंने घटनाओं के निष्पादन आदेश की जांच की है और यह मेरे डिजाइन के लिए अच्छा नहीं है। सबसे पहले यह उन सभी नोड्स के लिए OnMeasureItem ईवेंट को निकालता है जो प्रारंभ नहीं किया गया है, फिर यह OnGetText ईवेंट को कॉल करना शुरू कर देता है। मेरा मतलब है, लगता है कि हम 3 नोड्स है, घटनाओं इसी क्रम में सक्रिय किए जाएंगे:

OnMeasureItem for node 1 
OnMeasureItem for node 2 
OnMeasureItem for node 3 
OnGetText for node 1 
OnGetText for node 2 
OnGetText for node 3 

लेकिन मैं कुछ इस तरह की जरूरत है ताकि मैं लॉक कर सकते हैं:

OnMeasureItem for node 1 
OnGetText for node 1 

OnMeasureItem for node 2 
OnGetText for node 2 

OnMeasureItem for node 3 
OnGetText for node 3 

का सबसे अच्छा तरीका क्या है OnMeasureItem और OnGetText ईवेंट के बीच प्राप्त डेटा के सिंक्रनाइज़ेशन को बनाए रखें?

मैं अपने सरणी को सभी OnMeasureItem() और OnGetText() ईवेंट के दौरान लॉक नहीं करना चाहता हूं।

धन्यवाद।

जोड़ा गया OnTimer:

procedure TMainForm.SyncHexLog; 
begin 
    HexLog.BeginUpdate; 
    Try 
    if (HexLog.RootNodeCount <> FirpList.ComOperationCountLagged) then 
     begin 
      HexLog.RootNodeCount := FirpList.ComOperationCountLagged; 

      // measure for fast scrolling 
      HexLog.ReInitNode(HexLog.GetLastNoInit(), True);  

      if FAutoScroll then 
      begin 
      HexLog.ScrollIntoView(HexLog.GetLast, False, False); 
      end; 
     end; 
    Finally 
    HexLog.EndUpdate; 
    End; 
end; 
+0

प्रश्न में जोड़ा गया। –

+0

मैंने अपनी आखिरी टिप्पणी हटा दी है क्योंकि मैं भूल गया था कि आप 'toVariableNodeHeight' का उपयोग कर रहे हैं। बस एक अतिरिक्त (शायद अप्रासंगिक) प्रश्न। वर्चुअल ट्री व्यू का कौन सा संस्करण आप उपयोग कर रहे हैं? – TLama

+0

नवीनतम मुझे लगता है। मैंने एसवीएन से जांच की। // संस्करण 5.0.0 –

उत्तर

5

मैं MeasureItemHeight विधि के बाद के आह्वान के साथ नोड के राज्यों से vsHeightMeasured को हटाने के द्वारा मैन्युअल रूप से आइटम माप के लिए मजबूर करने की कोशिश करेंगे। यह OnMeasureItem फिर से ट्रिगर करेगा। समस्या फिर से है, क्योंकि आपको नोड के पाठ को बदलने के एक से अधिक बार आइटम को मापना नहीं चाहिए, लेकिन उस स्क्रॉलिंग सामग्री के कारण अभी भी OnMeasureItem को संभालना होगा।

तो जैसा कि आपने टिप्पणी में उल्लेख किया है, आप अपनी डेटा संरचना में अपना NodeMeasured ध्वज शामिल कर सकते हैं और नोड के पाठ को बदलते समय इसे रीसेट कर सकते हैं (जब आपके लॉग आइटम में कुछ डेटा बदल दिया जाता है) और आपके पास पास होने के बाद इसे सेट करें मजबूर नोड ऊंचाई माप के साथ OnGetText घटना। यहाँ एक स्यूडोकोड है:

procedure TForm1.VirtualStringTreeGetText(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; 
    var CellText: string); 
begin 
    ThreadList.LockList; 
    try 
    // check if the own flag which indicates that the text is new, that 
    // the data has changed since the last time you were here in OnGetText 
    // is False and if so, force the node measurement to set current node 
    // height and set this flag to True to remember we already did this 
    if not ThreadList.Items[Node.Index].NodeMeasured then 
    begin 
     // fake the node measurement, remove the measured flag 
     Exclude(Node.States, vsHeightMeasured); 
     // this will trigger the OnMeasureItem again because of removed 
     // vsHeightMeasured flag from the node's state 
     VirtualStringTree.MeasureItemHeight(VirtualStringTree.Canvas, Node); 
     // set the NodeMeasured flag to remember we've measured the item 
     ThreadList.Items[Node.Index].NodeMeasured := True; 
    end; 
    // here set the node's text and unlock your thread safe list 
    CellText := ThreadList[Node.Index].SomeText; 
    finally 
    ThreadList.UnlockList; 
    end; 
end; 

और अपने धागा जब डेटा बदल जाती है, तो आप गलत को यह NodeMeasured ध्वज सेट करने के लिए है।

if LogHasChanged then 
begin 
    ThreadList.LockList; 
    try 
    ThreadList.Items[X].NodeMeasured := False; 
    ThreadList.Items[X].SomeText := 'Something new'; 
    finally 
    ThreadList.UnlockList; 
    end; 
end; 
+0

मुझे लगता है "बहिष्कृत करें (नोड.स्टेट्स, बनाम हाइट माइसेसर)" पर्याप्त है। MeasureItemHeight() को कॉल करने की आवश्यकता नहीं है, है ना? ऐसा लगता है कि vsHeightMeasured को हटाने के बाद मेरी समस्या गायब हो गई। –

+0

यदि आप नोड राज्य से केवल 'बनामइटमाइज्ड' ध्वज को हटाते हैं, तो वर्तमान नोड की ऊंचाई को सेट करने के लिए 'ऑनमेजरइटम' को निकाल दिया जाना चाहिए। यह तब भी होता है जब पेड़ पेंट किया जाता है, लेकिन जैसा कि आपने कहा था कि नोड का डेटा (टेक्स्ट) 'ऑनमेजरइटम' और 'ऑनगेटटेक्स्ट' के बीच में बदल सकता है, इसलिए जब आप अपनी थ्रेड सूची को लॉक करते हैं तो आपको इसे मैन्युअल रूप से ट्रिगर करना चाहिए % सुनिश्चित करें कि आप उसी टेक्स्ट के लिए ऊंचाई माप रहे हैं जो आप प्रदर्शित करते हैं। – TLama

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