Mengaktifkan ITool khusus dari formulir tanpa menambahkannya ke toolbar ArcMap AddIn?

11

Saya sedang mengerjakan add-in untuk ArcMap 10.0 yang menambahkan toolbar ke ArcMap. Satu perintah ( OpenModelessDialogCommand) tombol pada toolbar yang membuka dialog WinForms modeless, dari mana alat ( MyTool) dapat diaktifkan untuk misalnya memilih fitur pada peta.

My Config.esriaddinxberisi deklarasi perintah dan toolbar ini:

<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>

Apa yang saya punya masalah dengan mengaktifkan MyTooldalam formulir. Yang saya temukan di internet adalah contoh kode di sepanjang baris:

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

Namun, ini tampaknya mengharuskan yang MyToolbenar - benar muncul di bilah perintah (misalnya bilah alat) dari add-in saya. Tapi bukan itu masalahnya. Jadi, saya sudah mencoba ini selanjutnya:

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

Saya bahkan telah melihat ke dalam menambahkan yang tidak terlihat AxToolbarControlke formulir saya dan menambahkan tombol untuk MyToolitu; tapi kemudian saya mengalami masalah tentang bagaimana menghubungkan bilah alat itu (via SetBuddyControl) ke peta dokumen yang dibuka. Saya tidak ingin alat berfungsi secara terpisah AxMapControl, saya ingin alat itu bekerja secara langsung dengan peta utama yang ditunjukkan di ArcMap.

Pertanyaan:
Bagaimana cara mengaktifkan alat khusus yang tidak ditambahkan ke bilah alat apa pun (atau bilah perintah lainnya, dalam hal ini)?

stakx
sumber
Jika menurut Anda jawaban saya akan berfungsi untuk Anda jika bilah perintah berfungsi seperti yang diiklankan, mungkin tambahkan tag "bug" ke pertanyaan Anda. Cucian kotor yang ditampilkan di depan umum seringkali merupakan motivasi yang baik bagi vendor untuk memperbaiki bug.
Kirk Kuykendall
@Kirk, saya akan melakukan itu, tapi saya tidak bisa - saya belum punya peringkat yang cukup di sini untuk membuat tag baru, dan bugsepertinya belum ada; silakan mengedit tag sendiri.
stakx

Jawaban:

7

Ini bekerja untuk saya menggunakan ArcGIS 10 SP1. Alat khusus saya tidak ada di bilah alat:

    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
Di seberang
sumber
1
+1 Jika ini berhasil, tentu ini lebih sederhana daripada jawaban yang saya posting. Saya cukup yakin saya sudah mencobanya tetapi sudah menginstal SP1, jadi mungkin itu faktornya.
Kirk Kuykendall
Jawaban lbross banyak membantu saya. Kemudian saya menemukan solusi yang hampir sama di pencari potongan ArcGis: 'Pernyataan - Gunakan Alat di Formulir Windows.
dpalmetz
Saya tidak dapat memberikan suara atau menambahkan komentar karena saya tidak memiliki reputasi yang cukup, tetapi jawaban lbross bekerja untuk saya di ArcGIS 10.2. Saya membuat ITool tanpa bilah alat dan menyebutnya dari tombol Windows Víctor
vaparicio
3

Saya belum pernah mencoba ini, tetapi sepertinya itu harus berfungsi: Dalam formulir modeless Anda memiliki dua variabel anggota, yang pertama (m_Tool) mereferensikan ITool Anda dan yang kedua (m_Application) mereferensikan IApplication. Dalam konstruktor untuk formulir modeless Anda, minta instantiate ITool dan panggil OnCreate , melewati referensi IApplication.

Pada formulir modeless Anda memiliki tombol itu, ketika diklik set m_Application. CurrentTool = m_Tool. Juga, daripada melakukan dialog modeless, saya akan merekomendasikan menggunakan jendela dockable mungkin menggunakan WPF di dalamnya .

Perbarui Dalam upaya untuk menebus posting ini, saya mencoba meretas sesuatu bersama-sama. Sepertinya Anda harus dapat membuat toolbar secara dinamis, menyembunyikannya, menambahkan alat ke sana (mendapatkan ICommandItem untuk diatur ke CurrentTool), lalu menghapus toolbar tanpa pengguna mengetahui bahwa alat itu ada di toolbar. Namun, ICommandBar.Dock dan ICommandItem.Delete tampaknya tidak berfungsi untuk tocar dinamis. IMHO ini adalah bug.

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(); 
    }
}
Kirk Kuykendall
sumber
1
Ini tidak akan berfungsi, karena properti CurrentTool mengharapkan ICommandItem. Referensi ICommandItem tidak dapat dibuat secara langsung, tetapi hanya dapat diambil melalui ICommandBars.
Petr Krebs
Cukup benar tentang currenttool, tetapi ICommandbar.Add menciptakan ICommandItem dari UID. Masalah kemudian menjadi bagaimana menyingkirkan bilah perintah setelah tidak lagi diperlukan (atau setidaknya menyembunyikannya).
Kirk Kuykendall
wow, terima kasih telah menambahkan contoh kode kerja di pembaruan Anda. Ini memalukan bahwa tidak Dockjuga tidak Deleteberfungsi, tetapi ini awal yang baik. Saya akan melihat Deletemasalah lebih lanjut, saya pikir.
stakx
ide yang sangat menarik, saya pasti akan mencoba menguraikannya. Btw, saya juga percaya perilaku yang Anda gambarkan adalah bug.
Petr Krebs
Saya akhirnya menggunakan solusi yang berbeda (antara lain, dengan membuat alat saya Singleton sehingga saya dapat dengan mudah mendapatkan referensi untuk itu; CommandBars.Findmasalah tiba-tiba terpecahkan sendiri, untuk beberapa alasan yang tidak diketahui), tetapi saya memberikan jawaban ini centang centang tandai karena ini mungkin apa yang akan saya lakukan.
stakx
3

Saya tidak tahu mengapa Anda perlu menambahkan alat di toolbar. Karena, saya telah bekerja dengan beberapa hal serupa dan saya belum menemukan kebutuhan untuk menambahkannya di bilah alat.

Dalam kasus saya, ketika pengguna mengklik tombol di jendela dockable, alat akan diaktifkan. Untuk melakukan pekerjaan ini, kelas alat saya terlihat seperti berikut:

  • Id alat saya adalah: "ArcMap_SelectionTool"
  • Nama kelas alat saya adalah: "SelectionTool"
  • Simpan bidang statis tipe pahat di kelas pahat

    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
    }

Jadi, setiap kali saya perlu instantiate alat ini, saya menyebutnya dengan cara berikut:

        var toolInstance = SelectionTool.Instance;

Setelah bekerja dengan alat ini, saya harus keluar dari alat contoh. Jadi saya sebut SelectionTool.ExitToolInstance()metode.

Prosedur ini berfungsi dengan baik untuk saya.

Emi
sumber
1

Saya biasanya menyelesaikan ini dengan membuat perintah (OpenModelessDialogCommand dalam kasus Anda) juga alat ( ITool). Setelah mengklik perintah, saya membuka formulir. Lalu saya juga bisa mengaktifkannya sebagai alat kapan saja.

Jika alat yang ingin Anda aktifkan bukan milik Anda, Anda dapat menyampaikan panggilan dari ITool Anda (diimplementasikan seperti di atas) ke instance alat lainnya.

Petr Krebs
sumber
0

Jika Anda memiliki akses ke objek peta, banyak alat dapat dijalankan dengan melakukan panggilan ke onCreate mengirim misalnya objek MapControl untuk menghubungkannya ke peta. Setelah itu hanya menjalankan metode onClick.

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

Jangan bekerja pada semua alat ESRI karena beberapa perlu ditambahkan ke toolbar.

MathiasWestin
sumber
Bagaimana saya mendapatkan referensi ke objek peta seperti itu? Yang bisa saya dapatkan hanyalah IMapantarmuka IMxDocument, tapi jelas itu tidak sama, kan?
stakx
Sunting: di Desktop, itu adalah Aplikasi yang merupakan objek kait: help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/…
MathiasWestin
maaf, saya mencoba ini; itu tidak bekerja. Masalahnya di sini adalah bahwa alat itu dibuat, tetapi tidak pernah diaktifkan. Kedua, saya masih tidak melihat bagaimana saya bisa mendapatkan MapControlobjek (jika saya benar-benar membutuhkannya) melalui IApplicationatau objek apa pun yang dapat dijangkau dari sana.
stakx
Anda harus meneruskan IApplication ke OnCreate ketika melakukan ini di Desktop, jika saya tidak salah membaca dokumentasi. Mengirim objek MapControl bekerja untuk saya di Engine.
MathiasWestin
tampaknya benar bahwa Anda akan meneruskan IApplicationobjek ke OnCreate- tetapi itu tidak cukup (setidaknya tidak untuk alat kustom saya), karena alat tidak diaktifkan oleh OnCreate, dan karenanya tidak akan menerima peristiwa input apa pun.
stakx