Özel ITool'u ArcMap AddIn araç çubuğuna eklemeden formdan etkinleştirmek ister misiniz?


11

ArcMap için bir araç çubuğu ekleyen ArcMap 10.0 için bir eklenti üzerinde çalışıyorum. OpenModelessDialogCommandBu araç çubuğundaki bir komut ( ) düğmesi, MyToolörneğin harita üzerinde bir özellik seçmek için bir aracın ( ) etkinleştirilebildiği , modelsiz bir WinForms iletişim kutusu açar .

Benim Config.esriaddinxşu komut ve araç çubuğu bildirimlerini içerir:

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

Sorun yaşadığım şey MyToolformda aktive etmek. İnternette bulduğum tek şey aşağıdaki kod örnekleri:

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

Ancak, görünüşe göre bu, eklentimin MyToolbir komut çubuğunda (örn. Araç çubuğu) görünmesini gerektirir . Ama durum böyle değil. Bunu bir sonraki denedim:

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

Hatta formuma görünmez AxToolbarControlbir ekleme ve MyToolorada bir düğme ekleme baktım ; ama sonra bu araç çubuğunu (üzerinden SetBuddyControl) açılan belgenin haritasına nasıl bağlayacağım konusunda sorunlar yaşıyorum . Aracın ayrı AxMapContrololarak çalışmasını istemiyorum, doğrudan ArcMap'ta gösterilen ana harita ile çalışmasını istiyorum.

Soru:
Herhangi bir araç çubuğuna (veya başka bir komut çubuğuna) eklenmeyen özel bir aracı nasıl etkinleştiririm?


Komut çubuğunun reklamı yapıldığı takdirde yanıtımın işinize yarayacağını düşünüyorsanız, sorunuza bir "hata" etiketi ekleyin. Halka açık olarak gösterilen kirli çamaşırlar, bir satıcı için bir hatayı düzeltmek için genellikle iyi bir motivasyon sağlar.
Kirk Kuykendall

@Kirk, bunu yapacağım, ama yapamam - Burada yeni etiketler oluşturmak için yeterli rütbem yok ve bughenüz var gibi görünmüyor; lütfen etiketleri kendiniz düzenlemekten çekinmeyin.
stakx

Yanıtlar:


7

Bu benim için ArcGIS 10 SP1 kullanarak çalıştı. Özel aracım araç çubuğunda değil:

    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 Bu işe yararsa, bu kesinlikle gönderdiğim yanıttan daha basittir. Bunu denedim ama SP1 yüklü beri eminim, bu yüzden belki bir faktör oldu.
Kirk Kuykendall

Lbross'un cevabı bana çok yardımcı oldu. Daha sonra ArcGis snippet bulucusunda hemen hemen aynı çözümü buldum: 'Statements - Windows Form.snippet'de bir Tool kullanın' (C # kullanıyorum) Çok daha az itibarım olduğu için cevabı oylayamıyorum.
dpalmetz

Oy kullanamıyorum veya yorum ekleyemiyorum çünkü yeterli itibarım yok, ancak lbross'un cevabı ArcGIS 10.2'de benim için çalışıyor. Bir araç çubuğu olmadan bir ITool oluşturdum ve bir Windows düğmesinden
çağırdım

3

Bunu hiç denemedim, ama işe yarayacak gibi görünüyor: Modelsiz formunuzda iki üye değişkeni var, ilk (m_Tool) ITool'ünüze ve ikinci (m_Application) IApplication'ye atıfta bulunuyor. Modelsiz formunuzun yapıcısında, ITool'u başlatmasını ve bir IA uygulama başvurusunu geçerek OnCreate'i çağırmasını sağlayın.

Modelsiz formunuzda, tıklandığında m_Application ayarlayan bir düğme bulunur. CurrentTool = m_Tool. Ayrıca, modelsiz bir diyalog yapmak yerine, belki de içinde WPF kullanarak takılabilir bir pencere kullanmanızı tavsiye ederim .

Güncelleme Bu topal yanıtı yayınlamak için bir şey denemek için, birlikte bir şeyler kesmek denedim. Bir araç çubuğunu dinamik olarak oluşturabilmeniz, gizleyebilmeniz, aracı buna ekleyebilmeniz (CurrentTool'a ayarlamak için bir ICommandItem alma) ve daha sonra kullanıcı aracın bir araç çubuğunda olduğunu bilmeden araç çubuğunu silmeniz gerekir. Ancak, ICommandBar.Dock ve ICommandItem.Delete dinamik çok çubuklar için çalışmıyor gibi görünüyor. IMHO bu bir hatadır.

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 özelliği bir ICommandItem beklediğinden bu çalışmaz. ICommandItem referansları doğrudan oluşturulamaz, ancak yalnızca ICommandBars aracılığıyla alınabilir.
Petr Krebs

Currenttool hakkında oldukça doğru, ancak ICommandbar.Add bir UID'den bir ICommandItem oluşturur. Sorun daha sonra artık gerekli olmadığında (veya en azından gizlediğinde) komut çubuğundan nasıl kurtulacağınız olur.
Kirk Kuykendall

vay, güncellemenize bir çalışma kodu örneği eklediğiniz için teşekkür ederiz. Ne işe yarayan ne Dockde Deleteişe yaramayan bir utanç , ama iyi bir başlangıç. Ben Deletekonuyu daha yakından inceleyeceğim.
stakx

ne ilginç bir fikir, ben kesinlikle bundan yola çıkmaya çalışacağım. Btw Ayrıca açıkladığınız davranışın bir hata olduğuna inanıyorum.
Petr Krebs

Farklı bir çözüm kullandım (diğer şeylerin yanı sıra, aracımı kolayca bir referans alabilmek için bir Singleton yaparak; CommandBars.Findsorun bilinmeyen bir nedenden dolayı aniden çözüldü), ancak bu cevabı işaretliyorum çünkü büyük olasılıkla bunu yapardım.
stakx

3

Aracı neden bir araç çubuğuna eklemeniz gerektiğini bilmiyorum. Çünkü, benzer bir şeyle çalıştım ve araç çubuğuna eklemeye gerek duymadım.

Benim durumumda, kullanıcı yerleştirilebilir pencerede bir düğmeyi tıklattığında, bir araç etkinleştirilir. Bu işi yapmak için, araç sınıfım aşağıdaki gibi görünüyor:

  • Araç kimliğim: "ArcMap_SelectionTool"
  • Araç sınıfı adım: "SelectionTool"
  • Araç sınıfında statik bir araç türü alanı tutma

    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
    }
    

Yani, bu aracı başlatmam gerektiğinde, şu şekilde adlandırıyorum:

        var toolInstance = SelectionTool.Instance;

Araçla çalıştıktan sonra, araç örneğinden çıkmam gerekiyor. Bu yüzden SelectionTool.ExitToolInstance()yöntemi çağırıyorum .

Bu prosedür benim için iyi çalışıyor.


1

Ben genellikle komut (sizin durumda OpenModelessDialogCommand) da bir araç ( ITool) yaparak çözmek . Komutu tıklattıktan sonra formu açıyorum. Sonra da her an bir araç olarak etkinleştirebilirim.

Etkinleştirmek istediğiniz araç size ait değilse, ITool'unuzdan (yukarıdaki gibi uygulanır) aramaları diğer araç örneğine aktarabilirsiniz.


0

Harita nesnesine erişiminiz varsa, örneğin MapControl nesnesini haritaya bağlamak için onCreate gönderimi çağrısı yapılarak birçok araç çalıştırılabilir. Bundan sonra sadece onClick yöntemini çalıştırmaktır.

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

Bazılarının bir araç çubuğuna eklenmesi gerektiğinden, tüm ESRI araçlarında çalışmaz.


Böyle bir harita nesnesine nasıl referans alabilirim? Ulaşabildiğim tek şey bir IMaparayüz IMxDocument, ama açıkça aynı değil, değil mi?
stakx

Düzenleme: Masaüstünde kanca nesnesi olan IA uygulama
MathiasWestin

üzgünüm, bunu denedim; çalışmıyor. Buradaki sorun, aracın oluşturulması, ancak hiçbir zaman etkinleştirilmemesidir. İkincisi, hala bir MapControlnesneyi (aslında birine ihtiyacım olursa) IApplicationveya oradan ulaşılabilecek herhangi bir nesneyi nasıl alabileceğimi göremiyorum .
stakx

Belgeleri yanlış okuyorsam, bunu Desktop'ta yaparken IApplication'yi OnCreate'a geçirmelisiniz. Bir MapControl nesnesinde gönderme benim için Engine'de çalışır.
MathiasWestin

bir IApplicationnesneyi iletmeniz doğru görünüyor OnCreate- ancak bu yeterli değil (en azından benim özel aracım için değil), çünkü araç etkinleştirilmiyor OnCreateve bu nedenle herhangi bir giriş olayı almıyor.
stakx
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.