कस्टम ITool को फॉर्म से जोड़कर बिना ArcMap AddIn टूलबार में सक्रिय किए?


11

मैं ArcMap 10.0 के लिए एक ऐड-इन पर काम कर रहा हूँ जो ArcMap के लिए एक टूलबार जोड़ता है। OpenModelessDialogCommandउस टूलबार पर एक कमांड ( ) बटन एक मॉडलवेट WinForms डायलॉग को खोलता है, जिसमें से एक टूल ( MyTool) सक्रिय किया जा सकता है ताकि उदाहरण के लिए मैप पर किसी फीचर का चयन किया जा सके।

मेरी Config.esriaddinxइन कमांड और टूलबार घोषणाएँ हैं:

<Commands>
  <!-- this is the command that opens the modeless WinForms form, from where
       MyTool is available: -->
  <Button id="OpenModelessFormCommand" ... />
  <!-- MyTool is not directly referenced in any toolbar defined in this file: -->
  <Tool id="MyTool" class="MyTool" ... />
</Commands>
<Toolbars>
  <Toolbar ...>
    <Items>
      <Button refID="OpenModelessFormCommand" />
    </Items>
  </Toolbar>
</Toolbars>

मुझे जो समस्या हो रही है MyToolवह फ़ॉर्म में सक्रिय हो रही है। मैंने इंटरनेट पर जो कुछ भी पाया है वह सभी की तर्ज पर कोड नमूने हैं:

// get a reference to an instance of MyTool:
ICommandItem myTool = ArcMap.Application.Document.CommandBars.Find("MyTool");
 // activate MyTool: 
ArcMap.Application.CurrentTool = myTool;

हालांकि, यह स्पष्ट रूप से आवश्यक है कि MyToolवास्तव में मेरे ऐड-इन के कमांड बार (जैसे टूलबार) में दिखाई देता है। लेकिन ऐसी बात नहीं है। इसलिए, मैंने इसके लिए अगला प्रयास किया है:

ITool myTool = new MyTool();
ArcMap.Application.CurrentTool = myTool;  // Type mismatch! An ICommandItem is expected.

मैंने AxToolbarControlअपने फॉर्म में एक अदृश्य जोड़ने और MyToolवहां के लिए एक बटन जोड़ने पर भी ध्यान दिया है ; लेकिन फिर मैं उस टूलबार (कैसे SetBuddyControl) को खोला दस्तावेज़ के नक्शे से कनेक्ट करने की समस्याओं पर चल रहा हूं । मैं टूल को अलग AxMapControlसे काम नहीं करना चाहता , मैं चाहता हूं कि यह सीधे आर्कपॅप में दिखाए गए मुख्य नक्शे के साथ काम करे।

प्रश्न:
मैं एक कस्टम टूल को कैसे सक्रिय करूं जो किसी भी टूलबार (या अन्य कमांड बार, उस मामले के लिए) में नहीं जोड़ा गया है?


अगर आपको लगता है कि कमांडर के रूप में काम करने पर मेरा जवाब आपके लिए काम करेगा, तो अपने प्रश्न में "बग" टैग जोड़ें। सार्वजनिक रूप से दिखाए गए गंदे कपड़े धोने के लिए अक्सर एक विक्रेता को बग को ठीक करने के लिए अच्छी प्रेरणा होती है।
किर्क कुएकेन्डल

@Kirk, मैं ऐसा करने जा रहा था, लेकिन मैं नहीं कर सकता - मुझे नए टैग बनाने के लिए यहां पर्याप्त रैंक नहीं मिला है, और bugअभी तक मौजूद नहीं है; कृपया अपने आप को टैग संपादित करने के लिए स्वतंत्र महसूस करें।
स्टैक

जवाबों:


7

यह मेरे लिए ArcGIS 10 SP1 का उपयोग कर काम किया। मेरा कस्टम टूल टूलबार पर नहीं है:

    Dim UIDCls As ESRI.ArcGIS.esriSystem.UID = New ESRI.ArcGIS.esriSystem.UIDClass()
    ' id property of menu from Config.esriaddinx document
    UIDCls.Value = "ClassLibraryAddin_MyTool"
    Dim document As ESRI.ArcGIS.Framework.IDocument = My.ArcMap.Document
    Dim commandItem As ESRI.ArcGIS.Framework.ICommandItem = TryCast(document.CommandBars.Find(UIDCls), ESRI.ArcGIS.Framework.ICommandItem)
    If commandItem Is Nothing Then
        Exit Sub
    End If
    My.ArcMap.Application.CurrentTool = commandItem

1
+1 यदि यह काम करता है, तो यह निश्चित है कि मैंने जो उत्तर पोस्ट किया है, उससे अधिक सरल है। मुझे पूरा यकीन है कि मैंने कोशिश की है, लेकिन जब से SP1 स्थापित किया है, तो शायद वह एक कारक था।
किर्क कुएकेन्डल

Lbross के जवाब से मुझे बहुत मदद मिली। बाद में मैंने आर्कजीस स्निपेट खोजक में लगभग एक ही समाधान पाया: 'स्टेटमेंट्स - विंडोज फॉर्म में एक टूल का उपयोग करें। Snippet' (मैं C # का उपयोग कर रहा हूं) मैं जवाब को वोट नहीं दे सकता क्योंकि मेरे पास बहुत कम प्रतिष्ठा है।
dpalmetz

मैं वोट नहीं दे सकता या टिप्पणी नहीं कर सकता क्योंकि मेरे पास पर्याप्त प्रतिष्ठा नहीं है, लेकिन आर्कबिस 10.2 में मेरे लिए lbross answers जवाब काम करता है। मैंने एक टूलबार के बिना एक ITool बनाया और इसे विंडोज बटन से बुलाया Víctor
vaparicio

3

मैंने कभी यह कोशिश नहीं की है, लेकिन ऐसा लगता है कि यह काम करना चाहिए: आपके मॉडल रूप में दो सदस्य चर हैं, पहला (m_Tool) आपके ITool का संदर्भ देता है और दूसरा (m_Application) IApplication का संदर्भ देता है। अपने मोडहीन फार्म के लिए निर्माता में, यह iTool का दृष्टांत और कॉल OnCreate , एक IApplication संदर्भ गुजर।

आपके मॉडल रूप में एक बटन होता है, जब क्लिक किया गया सेट m_Application। CurrentTool = m_Tool। इसके अलावा, एक मॉडलिंग संवाद करने के बजाय, मैं एक डॉक करने योग्य विंडो का उपयोग करने की सलाह दूंगा जो शायद इसके भीतर WPF का उपयोग कर रहा हो

अद्यतन इस लंगड़ा जवाब पोस्ट करने के लिए प्रायश्चित करने के प्रयास में, मैंने एक साथ कुछ हैक करने की कोशिश की है। ऐसा लगता है कि आपको डायनामिक रूप से टूलबार बनाने में सक्षम होना चाहिए, इसे छिपाना चाहिए, इसमें टूल जोड़ना होगा (करेंटमूल को सेट करने के लिए एक ICommandItem), फिर टूलबार पर टूल को चालू किए बिना उपयोगकर्ता को टूलबार हटा दें। हालाँकि, ICommandBar.Dock और ICommandItem.Delete गतिशील टोबार के लिए काम नहीं करते हैं। IMHO यह एक बग है।

protected override void OnClick()
{
    UID uid = new UIDClass();
    uid.Value = "Microsoft_ArcMapAddin1_Tool1";
    var bar = ArcMap.Application.Document.CommandBars.Create("mybar", esriCmdBarType.esriCmdBarTypeToolbar)
        as ICommandBar;

    // bug, dock doesn't work ...
    bar.Dock(esriDockFlags.esriDockHide);
    bar.Add(uid);

    var itm = bar.Find(uid);
    if (itm != null)
    {
        ArcMap.Application.CurrentTool = itm;
        // bug, delete doesn't work either
        ((ICommandItem)bar).Delete(); 
    }
}

1
यह काम नहीं करेगा, क्योंकि CurrentTool संपत्ति एक ICommandItem की अपेक्षा करती है। ICommandItem संदर्भ सीधे नहीं बनाया जा सकता है, लेकिन केवल ICommandBars के माध्यम से पुनर्प्राप्त किया जा सकता है।
पेट्र क्रेब्स

करंट के बारे में काफी सही है, लेकिन ICOMandbar.Add एक UID से ICommandItem बनाता है। समस्या तब हो जाती है कि कमांडर से छुटकारा पाने के बाद अब इसकी आवश्यकता नहीं है (या कम से कम इसे छिपाकर)।
किर्क कुएकेन्डल

वाह, आपके अपडेट में एक वर्किंग कोड उदाहरण जोड़ने के लिए धन्यवाद। यह शर्म की बात है कि न तो है Dockऔर न ही Deleteकाम है, लेकिन यह एक अच्छी शुरुआत है। मैं Deleteआगे के मुद्दे पर विचार करूंगा।

क्या एक दिलचस्प विचार है, मैं निश्चित रूप से उस से विस्तार करने की कोशिश करेंगे। Btw मैं यह भी मानता हूं कि आपके द्वारा वर्णित व्यवहार एक बग है।
पेट्र क्रेब्स

मैंने अपने टूल को सिंगलटन बनाकर एक अलग समाधान (अन्य चीजों के बीच) का उपयोग किया, ताकि मैं आसानी से इसका संदर्भ प्राप्त कर सकूं; CommandBars.Findसमस्या अचानक किसी अज्ञात कारण से हल हो गई), लेकिन मैं इसका जवाब दे रहा हूं टिक निशान क्योंकि यह शायद मैंने क्या किया है।
स्टैकएक्स

3

मुझे नहीं पता कि आपको टूलबार में टूल जोड़ने की आवश्यकता क्यों है। क्योंकि, मैंने कुछ इसी तरह की चीज के साथ काम किया है और मुझे इसे टूल बार में जोड़ने की कोई आवश्यकता नहीं है।

मेरे मामले में, जब उपयोगकर्ता डॉक करने योग्य विंडो में एक बटन पर क्लिक करता है, तो एक उपकरण सक्रिय हो जाता है। इस कार्य को करने के लिए, मेरा उपकरण वर्ग निम्न प्रकार दिखता है:

  • मेरी टूल आईडी है: "ArcMap_SelectionTool"
  • मेरा टूल क्लास का नाम है: "SelectionTool"
  • उपकरण वर्ग में उपकरण प्रकार का स्थिर क्षेत्र रखें

    private static ICommandItem _selectionTool;
    private static SelectionTool _instance;
    public static SelectionTool Instance
    {
        get
        {
            if (_instance == null)
            {
                var selectionToolUID = new UID();
                selectionToolUID.Value = "ArcMap_SelectionTool";
                _selectionTool = ArcMap.Application.Document.CommandBars.Find(selectionToolUID, false, false);
                if (_selectionTool == null)
                {
                    MessageBox.Show("Selection tool is not found.");
                    return null;
                }
            }
            if (_selectionTool != null)
                ArcMap.Application.CurrentTool = _selectionTool;
            return _instance;
        }
    }
    
    public static void ExitToolInstance()
    {
        if (_instance != null)
            ArcMap.Application.CurrentTool = null;
    }
    
    public SelectionTool()
    {
        _instance = this;
    }
    
    protected override void OnMouseDown(MouseEventArgs arg)
    {
        if (arg.Button != MouseButtons.Left)
            return;
        //Do Work
    }

इसलिए, जब भी मुझे इस टूल को इंस्टेंट करने की आवश्यकता होती है, मैं इसे निम्नलिखित तरीके से कॉल करता हूं:

        var toolInstance = SelectionTool.Instance;

टूल के साथ काम करने के बाद, मुझे टूल इंस्टेंस से बाहर निकलने की आवश्यकता है। तो मैं SelectionTool.ExitToolInstance()विधि कहता हूं ।

यह प्रक्रिया मेरे लिए ठीक काम करती है।


1

मैं आमतौर पर कमांड (OpenModelessDialogCommand आपके मामले में) भी एक उपकरण ( ITool) बनाकर इसे हल करता हूं । कमांड पर क्लिक करने पर, मैं फॉर्म खोलता हूं। फिर मैं किसी भी क्षण इसे एक उपकरण के रूप में सक्रिय कर सकता हूं।

यदि आप जिस टूल को सक्रिय करना चाहते हैं वह आपका अपना नहीं है, तो आप अपने ITool (ऊपर के रूप में कार्यान्वित) से कॉल को अन्य टूल इंस्टेंस पर रिले कर सकते हैं।


0

यदि आपके पास मैप ऑब्जेक्ट तक पहुंच है, तो मैप को कांट-छांट करने के लिए मैपकंट्रोल ऑब्जेक्ट को उदाहरण के लिए भेजने के लिए कॉल करके कई टूल चलाए जा सकते हैं। उसके बाद यह केवल ऑनक्लिक विधि को चलाने के लिए है।

tool.OnCreate(control.Object)
tool.OnClick()

सभी ईएसआरआई टूल पर काम न करें क्योंकि कुछ को टूलबार में जोड़ा जाना चाहिए।


मुझे ऐसे मानचित्र ऑब्जेक्ट का संदर्भ कैसे मिलेगा? मैं कभी भी प्राप्त कर सकते हैं लगता है के IMapमाध्यम से एक अंतरफलक है IMxDocument, लेकिन स्पष्ट रूप से यह एक ही नहीं है, है ना?
स्टाॅक्स

संपादित करें: डेस्कटॉप में यह IApplication
MathiasWestin

क्षमा करें, मैंने यह कोशिश की; यह काम नहीं करता है। यहां समस्या यह है कि उपकरण बन जाता है, लेकिन कभी सक्रिय नहीं होता है। दूसरा, मैं अभी भी नहीं देखता कि मैं कैसे एक MapControlवस्तु प्राप्त कर सकता हूं (यदि मुझे वास्तव में एक की आवश्यकता है) IApplicationया किसी वस्तु को वहां से प्राप्त करने के लिए।
स्टाॅक्स

डेस्कटॉप में ऐसा करने पर आपको IApplication में OnCreate में पास होना चाहिए, अगर मैं डॉक्यूमेंटेशन को गलत नहीं कर रहा हूं। MapControl ऑब्जेक्ट में भेजना इंजन में मेरे लिए काम करता है।
मैथियासवेस्टिन

यह सही लगता है कि आप किसी IApplicationऑब्जेक्ट को पास करेंगे OnCreate- लेकिन यह पर्याप्त नहीं है (कम से कम मेरे कस्टम टूल के लिए नहीं), क्योंकि टूल द्वारा सक्रिय नहीं होता है OnCreate, और इसलिए कोई इनपुट इवेंट प्राप्त नहीं करेगा।
स्टैक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.