2013-04-11 4 views
5

पर आधारित बटन सक्षम हो सकें। मैं एक्सेल के लिए एक VSTO रिबन एडइन बना रहा हूं, और मैं अपने एप्लिकेशन में कुछ कार्यपुस्तिका राज्य जानकारी संग्रहीत कर रहा हूं जिसका उपयोग मैं विजुअल बटन सक्षम करने के लिए करता हूं। इस बात को ध्यान में रखते हुए मैं इस कार्य ऑब्जेक्ट को इस एड ऑब्जेक्ट में एक शब्दकोश में संग्रहीत कर रहा हूं। मेरी समस्या यह है कि मुझे नहीं पता कि कार्यपुस्तिका के लिए एक अद्वितीय हैश/कुंजी/गाइड कैसे प्राप्त करें क्योंकि मुझे जो भी मिलता है वह एक COM wrapper है जो लगातार हैश को बदलता है। काफी उचित, मैं इसे पूरी तरह से समझता हूं।VSTO में एक्सेल वर्कबुक के लिए हैशकोड प्राप्त करें ताकि

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

मुझे अभी एक विचार था कि मुझे लगता है कि मैं कर सकता था Workbook_Open ईवेंट पर इस मार्गदर्शिका को रीफ्रेश करें। लेकिन फिर भी यह एक डोडी समाधान की तरह लगता है।

दूसरा समाधान मैं यहाँ पाया: http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/04efa74d-83bd-434d-ab07-36742fd8410e/

तो मुझे लगता है कि लोगों को कोड का इस्तेमाल किया और बनाया इस:

public static class WorkbookExtensions 
{ 
    public static IntPtr GetHashery(this msExcel.Workbook workbook) 
    { 
     IntPtr punk = IntPtr.Zero; 
     try 
     { 
      punk = Marshal.GetIUnknownForObject(workbook); 
      return punk; 
     } 
     finally 
     { 
      //Release to decrease ref count 
      Marshal.Release(punk); 
     } 
    } 
} 

यह कुछ मिनट के लिए बहुत अच्छी तरह से काम करता है, जब तक यह मुझे बदनाम देने शुरू होता है त्रुटि "COM ऑब्जेक्ट जिसे इसके अंतर्निहित आरसीडब्ल्यू से अलग किया गया है, का उपयोग नहीं किया जा सकता है" एप्लिकेशन का उपयोग करते समय .ActiveWorkbook।

क्या यह वर्कबुक COM ऑब्जेक्ट को संदर्भित करने का एक सुरक्षित तरीका है? क्या होगा यदि मेरे पास एक ही कार्यपुस्तिका GUID प्राप्त करने के लिए इस विधि का उपयोग करके दो रिबन अनुप्रयोग थे? क्या होगा यदि उनमें से एक एप्लिकेशन मेरे राज्य ऑब्जेक्ट पर कचरा कलेक्टर चलाता है, जो मार्शल को कॉल करने के लिए फाइनलज़र कहता है। FinalReleaseComObject (कार्यपुस्तिका)? क्या कोई तरीका है कि मैं वर्कबुक के लिए रेफ गिनती प्राप्त कर सकता हूं ताकि अन्य रिबन ऐप्स उनके साथ समाप्त होने से पहले मैं FinalRelease को कॉल न करूं? इन अन्य ऐप्स के साथ मेले खेलने के लिए VSTO में वर्कबुक COM ऑब्जेक्ट्स को साफ़ करने के लिए कुछ सर्वोत्तम अभ्यास क्या हैं?

निश्चित रूप से मैं वर्कबुक स्थिति के आधार पर बटन सक्षम करने वाला पहला व्यक्ति नहीं हूं, यह सब कैसे करते हैं? मैंने स्टैक ओवरफ़्लो पर कुछ अन्य लेख यहां देखे हैं लेकिन वर्कबुक गाइड समाधान के साथ मुझे कोई भी मदद नहीं करता है।

मैं रिबन डिजाइनर का उपयोग कर रहा हूं, और वर्कबुक लोड और निष्क्रिय घटनाओं को जोड़ रहा हूं।

अग्रिम धन्यवाद, उम्मीद है कि इसमें सभी विवरण शामिल हैं।

+1

** COM ऑब्जेक्ट को अपने अंतर्निहित आर से अलग कर दिया गया है सीडब्लू का उपयोग नहीं किया जा सकता ** - हाँ, मैं इस त्रुटि को पीआईटीए से नफरत करता हूं, इसे पढ़ें: http://jake.ginnivan.net/vsto-com-interop –

+1

आप एक ही फ़ंक्शन में IU अज्ञात सूचक क्यों जारी करते हैं? इसे रखने की कोशिश करें और इसे तब जारी करें जब कार्यपुस्तिका बंद हो या ऐसा कुछ हो। –

+0

शानदार, धन्यवाद @ जेरेमी थॉम्पसन! उस लेख से सीखने के लिए बहुत कुछ है। VSTOContrib ऐसा लगता है कि यह मेरी अगली परियोजना के लिए बहुत अच्छा होगा, लेकिन यह मेरी तत्काल समस्याओं को हल नहीं करता है। @ सिमोन मॉरीयर - मैं देशी कोड के साथ बहुत जानकार नहीं हूं, लेकिन मुझे लगता है कि अगर मैं यहां पॉइंटर जारी नहीं करता हूं तो मैं इसे बाद में रिलीज़ करने के लिए ट्रैक खो दूंगा? – stuzor

उत्तर

5

मैंने इंटप्रेट को लंबे समय तक कास्टिंग करके इसे हल किया, और फिर IntPtr का निपटान मुझे प्रभावित नहीं करता है। मुझे IntPtr को संरक्षित करने की आवश्यकता नहीं है क्योंकि मुझे वास्तव में कार्यपुस्तिका के बारे में कुछ अद्वितीय है।

निम्न कोड मुझे वर्कबुक-विशिष्ट राज्य जानकारी संग्रहीत करने की अनुमति देता है, इसलिए मैं कस्टम ऑब्जेक्ट कार्यपुस्तिका स्थिति के आधार पर अपने रिबन में बटन की दृश्य स्थिति अपडेट कर सकता हूं। आप अपनी कस्टम वर्कबुकस्टेट क्लास में जो भी जानकारी चाहते हैं उसे स्टोर कर सकते हैं, लेकिन आमतौर पर यह सत्र-विशिष्ट जानकारी होगी जिसे आप स्प्रेडशीट में ही नहीं रखना चाहते हैं।

अलग वर्कबुक एक्सटेंशन:

public static class WorkbookExtensions 
{ 
    public static long GetHashery(this msExcel.Workbook workbook) 
    { 
     if (workbook == null) 
     { 
      throw new ArgumentNullException("workbook"); 
     } 

     IntPtr pUnknown = IntPtr.Zero; 
     try 
     { 
      pUnknown = Marshal.GetIUnknownForObject(workbook); 
      return pUnknown.ToInt64(); 
     } 
     finally 
     { 
      // GetIUnknownForObject causes AddRef. 
      if (pUnknown != IntPtr.Zero) 
      { 
       Marshal.Release(pUnknown); 
      } 
     } 
    } 
} 
तब मेरे VSTO/ExcelDna ThisAddIn कक्षा में

मैं उपरोक्त विधि के साथ सभी कार्यपुस्तिका राज्यों का एक नक्शा स्टोर एक अनूठा कार्यपुस्तिका हैश कुंजी खोजने के लिए:

private Dictionary<long, WorkbookState> _workbookStates = new Dictionary<long, WorkbookState>(); 
public WorkbookState WorkbookState 
{ 
    get 
    { 
     long hash = Application.ActiveWorkbook.GetHashery(); 
     WorkbookState state; 
     if (!_workbookStates.TryGetValue(hash, out state)) 
     { 
      state = _workbookStates[hash] = new WorkbookState(); 
     } 
     return state; 
    } 
} 

और निश्चित रूप से अब मैं अपने रिबन एप्लिकेशन में कहीं से भी अपने वर्कबुकस्टेट तक ThisAddIn.WorkbookState

+1

यह कार्यवाही से बुलाए जाने पर ActiveWorkbook के लिए एक और हैश देता है। – smg

+0

मुझे शीश और रिबन से हैश विधि को कॉल करने से दो अलग-अलग लंबे समय मिलते हैं –

+0

एमएमएम आप अच्छे अंक @ChrisHayes और user3009578 उठाते हैं। मैंने तब से सीखा है कि ActiveWorkbook को केवल यूआई थ्रेड से ही बुलाया जाना चाहिए। चूंकि ActiveWorkbook बदल सकता है, UI थ्रेड की तुलना में किसी भी थ्रेड से इसे संदर्भित करना एक खराब रणनीति है। इसलिए मैंने पाया है कि उपयोगकर्ता कार्रवाई ईवेंट हैंडलर में ActiveWorkbook को कैश करना सर्वोत्तम रणनीति है, और सभी थ्रेड के लिए उस ActiveWorkbook का उपयोग करें। यदि पृष्ठभूमि धागे को उपयोगकर्ता कार्रवाई के बिना ActiveWorkbook तक पहुंचने की आवश्यकता है, तो एप्लिकेशन को सुनकर अपनी स्वयं की प्रति कैश करें .ActiveWorkbookChanged ईवेंट।^_^डाउनवोट करने की कोई ज़रूरत नहीं है – stuzor

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