ArcObjects (ArcGIS pro Desktop a C #): Jak vrhat mezi uživatelské rozhraní ArcMap COM a mé vlastní objekty .Net UserControl?

Vytvářím obslužný program pro spuštění v ArcGIS pro stolní počítače pomocí ArcObjects (9.3.1 SDK) a C #. Net. Můj prototyp zahrnuje panel nástrojů se dvěma kombinované pole a nástroj. První kombinace vybírá vrstvu v TOC a druhá vybere pole z vybrané vrstvy. Nástroj bude použit k interakci s mapou.

V zásadě chci vybrat vrstvy, vyberte platné pole, poté klikněte na prvek v mapě a získejte jeho hodnotu pro vybrané pole. Zde je obrázek panelu nástrojů, pokud to pomůže:

zde zadejte popis obrázku

[otázka téměř úplně přeformulovaná odtud dolů]

Problém, který mám, je předávání stavu mezi nativními částmi uživatelského rozhraní COM a mými vlastními ovládacími prvky .Net. Například chci zachytit událost DropDownClosed na kombinovaném poli Layer, sestavit platný seznam sloupců vzhledem k této vrstvě a poté použít seznam názvů polí (přes IFields) do kombinovaného pole Fields.

After použitím některých počátečních komentářů RagiYaserBurham a blah238 a jejich sloučením s podrobnostmi z této stránky přejde následující obslužný program události DropDownClosed z kombinovaného pole zpět na panel nástrojů ( ICommandBar), ale nerozumím tomu, jak vracet z ICommandItem zpět k mé implementaci pole Fields v UserControl:

private void layerSelectCBO_DropDownClosed(object sender, EventArgs e) { _completionNotify.SetComplete(); string layerName = (sender as ComboBox).SelectedItem as string; // These two lines are a combination of initial commenter suggestions. ICommandItem toolbar = _iApp.Document.CommandBars.Find("ArcProject.UI.AngryToolbar", false, false); ICommandItem fieldsItem = (toolbar as ICommandBar).Find("ArcProject.UI.FieldSelectUC", false); } 

Takže .. teď, Jsem tady .. jak vrhám fieldItem na FieldSelectUC?

[ Řešení ]

Jak navrhl blah238, zkusil jsem casting ICommandItem.Command do své vlastní implementace UserControl a to udělal trik.

Nejprve jsem do svého FieldSelectUC UserControl musel přidat veřejného přístupového objektu, abych vrátil odkaz na jeho ComboBox; tento jednoduchý přístupový objekt vypadá takto:

// fieldSelectCBO is the name of the combobox control in the design view.. public ComboBox FieldsComboBox { get { return fieldSelectCBO; } } 

Po zavedení této úpravy se zde nachází obslužná rutina DropDownClosed, která vyplní pole Combox Fields všemi poli vybraná vrstva:

private void layerSelectCBO_DropDownClosed(object sender, EventArgs e) { _completionNotify.SetComplete(); string layerName = (sender as ComboBox).SelectedItem as string; // get the toolbar.. ICommandItem toolbar = _iApp.Document.CommandBars.Find("ArcProject.UI.AngryToolbar", false, false); // get my fields combo by way of CommandItem.Command.. ICommandItem fieldsCI = (toolbar as ICommandBar).Find("ArcProject.UI.FieldSelectUC", false); FieldSelectUC fieldsUC = fieldsCI.Command as FieldSelectUC; ComboBox fieldsComboBox = fieldsUC.FieldsComboBox; // get the fields for the selected layer.. IFields fields = null; int layerCount = _iDoc.FocusMap.LayerCount; int i; for (i = 0; i < layerCount; i++) { if (_iDoc.FocusMap.get_Layer(i).Name == layerName) { if (_iDoc.FocusMap.get_Layer(i) is FeatureLayer) { fields = (_iDoc.FocusMap.get_Layer(i) as FeatureLayer).FeatureClass.Fields; } } } // Build a list of field names for the combobox items.. List<string> fieldNameList = new List<string>(); if (fields != null) { int fieldCount = fields.FieldCount; int j; for (j = 0; j < fieldCount; j++) { string oneFieldName = fields.get_Field(j).Name; fieldNameList.Add(oneFieldName); } } // Populate the combobox items.. if (fieldNameList.Count > 0) { fieldsComboBox.Items.Clear(); foreach (string fieldName in fieldNameList) { fieldsComboBox.Items.Add(fieldName); } fieldsComboBox.SelectedItem = fieldsComboBox.Items[0]; } else { fieldsComboBox.Items.Add("Error: No fields!"); } } 

Toto je stále špinavé testovací lůžko (odtud AngryToolbar). Řešení však ukazuje, jak začít od rozšířeného UserControl, který implementuje ICommand a IToolControl a přejít zpět na součást .Net. Opravdu si vážím pomoci každého, kdo nabídl návrhy. Děkuji moc. 🙂

Komentáře

  • Jak o tom, jak vytvořit svůj proměnný layerName veřejný statický rozsah?
  • @ artwork21, to zní dobře, ale stále si ‚ nejsem jistý, jak získat přístup k instanci kteréhokoli comboboxu z jeho protějšek na panelu nástrojů? Víte, co tím myslím? Mám podezření, že ‚ je jednoduchá základní věc, kterou si ‚ nevím.
  • To zní jako rozdíl naléhavá otázka. ‚ Nevím, proč to musíte udělat. Zdá se mi, že Fields combobox by měl být vyčištěn a znovu osídlen na základě kombinace vrstev. Kombinovaný seznam vrstev by měl být vyplněn na základě posluchače událostí dokumentu.
  • @RichWawrzonek, který je přesně ten pravý. Ale ‚ si nejsem jistý, jak se dostat k existující instanci pole Fields z kombinace Layers. Ostatně musí nástroj přečíst obě jejich hodnoty.

Odpověď

Jak tomu dobře rozumím, máte dva .NET ComboBoxy na UserControl, který implementuje ICommand a IToolControl, a chcete získat odkaz na jedno z polí se seznamem od druhého. Pokud jsou ve stejném rozsahu, měli byste je být schopni odkázat na jejich názvy proměnných (zkontrolujte názvy návrhových prvků v návrháři UserControl).

Pokud jsou dvě pole se seznamem na samostatných UserControls, pak zkuste přenést ICommandItem.Command na svůj jiný UserControl.

Některé příklady najdete v této ukázce v nápovědě k verzi 9.3: Nedávno použité soubory – Command, MultiItem a ToolControl

Také zde je příspěvek na fóru ESRI pojednávající o tomto problému: http://forums.esri.com/Thread.asp?c=93&f=993&t=170088

Komentáře

  • Bingo. Tento řádek udělal trik, jak se dostat z instance ICommandItem zpět do UserControl třídy, kterou jsem implementoval: FieldSelectUC fs = fieldsItem.Command as FieldSelectUC; Nyní vidím všechny své ‚ s rekvizity v debuggeru. Obrovská díky vám.
  • Hurá! ‚ už nějakou dobu používám doplňky exkluzivně, takže jsem musel kopat nějaké staré věci, abych si vzpomněl, jak to všechno fungovalo 🙂 Taková věc je mnohem jednodušší (i když je to pravda méně flexibilní) s doplňky v 10, protože existuje specifický typ ComboBoxu a můžete pouze odkazovat na další komponenty doplňku se statickými proměnnými a metodami.
  • Ano, rozhodně se to díky novým doplňkům zdálo jednodušší. Při zkoumání tohoto jsem zjistil doplňky a doplňky, které ale pro moji implementaci prostě nebyly k dispozici ‚ t. Příklad GraphicsLayerToolControl v nápovědě .Net (v mém systému je tato adresa C:\Program Files (x86)\ArcGIS\DeveloperKit\SamplesNET\Desktop\GraphicsLayerToolControl\CSharp\GraphicsLayerToolControl2008.sln), která mi pomohla začít s UserControl a událostmi, ale prostě jsem nemohl ‚ Přišlo na to, jak prorazit díru do .Net z ovládacího prvku COM. Nemohu ‚ přehánět, jak jsem vděčný. S pozdravem.

Odpovědět

Kdykoli udělám takové věci, uložím názvy vrstev a polí do statické sada vlastností obsažená na panelu nástrojů. Poté pomocí obslužné rutiny události dokumentu zkontroluji, zda jsou vrstvy přidány / odebrány z ArcMap nebo zda je dokument změněn. Vlastnosti vrstvy a pole se aktualizují pokaždé, když je uživatel v rozevírací nabídce změní. Pokud je vrstva odstraněna z ArcMap nebo je dokument uzavřen, jsou resetovány na hodnotu null. Pak stačí zkontrolovat nulové hodnoty před spuštěním programu.

Získejte odkaz na kombinovaný modul prostřednictvím rozhraní ICommandItem:

ICommandItem panel nástrojů = _iApp.Document.CommandBars.Find („ArcProject.UI.AngryToolbar“, false, false);
ICommandItem fieldsItem = (panel nástrojů jako ICommandBar) .Find („ArcProject.UI.FieldSelectUC“, false); IComboBox cbo = (IComboBox) fieldsItem; // Potřebuje odkaz na ESRI.ArcGIS.SystemUI;

Komentáře

  • +1, aby to znělo tak snadno. 🙂 Ale problém, který mám, je přístup k vlastnostem již vytvořeného ovládacího prvku z hlediska jakéhokoli jiného ovládacího prvku. Líbí se mi váš nápad umístit jejich sdílené vlastnosti na panel nástrojů, můžete aktualizovat svou odpověď a ukázat, jak mohu ve skutečnosti přečíst vlastnosti obsahujícího panelu nástrojů z pohledu jednoho z komboboxů? ‚ Protože to ‚ je v podstatě to, co jsem ‚ m poté. Už vím, jak používat události dokumentu k naslouchání změnám obsahu, takže s tímto aspektem nepotřebuji ‚ pomoc. Děkujeme za odpověď.
  • @elrobis Sdílený stav můžete také umístit do samotného ICommandu (protože vždy bude existovat pouze jedna instance) a poté nechat ovládací prvky získat popisovač příkazu pomocí help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/…
  • Ragi je že jo. Protože používáte panel nástrojů COM, stačí předat uid vašeho comboboxu metodě ICommandBar.Find a získat odkaz. Jeho odkaz to všechno vysvětluje.
  • Líbí se mi také Ragi ‚ nápad. Chybí mi však něco zásadního. Například tento řádek vrací nulový panel nástrojů (kde this je UserControl s popiskem a komboboxem): ICommandBar toolbar = this.Parent as ICommandBar; Je to ‚ tento druh základního přechodu objektů uživatelského rozhraní, který mě zabíjí. ‚ nevím, jak se vrátit na panel nástrojů a implementovat některý z vašich návrhů. (A vlastně se mi myšlenka těchto vars na panelu nástrojů trochu líbí. Já to ‚ d pravděpodobně udělám přidáním veřejného getru na panel nástrojů, který aplikuje Ragi ‚ s nápadem). Děkujeme za vaši další pomoc.
  • Nemyslím si ‚ že this.Parent je platný pro rozhraní COM – to je koncept .NET / Windows Forms. Nechcete ‚ přejít “ přes uživatelské rozhraní „, chcete přistupovat k ICommands podle jejich ID.

Odpověď

Měl jsem podobný problém s vlastním nástrojem. Mám vlastní formulář, který se otevře tlačítkem na panelu nástrojů AddIn-Tool v ArcGis 10.x. Na tomto formuláři je tlačítko, které by mělo načíst souřadnice kliknutí na mapě, včetně přitahování. Mohl jsem spustit nástroj a zvládnout kliknutí na mapě, ale nemohl jsem získat hodnotu zpět do svého formuláře, protože cast do vlastního nástroje vždy selhal. Řešením bylo použít AddIn z ESRI.ArcGIS.Desktop.AddIns. Díky tomu bylo snadné získat přístup ke všem vlastnostem a metodám mého vlastního nástroje. Dokumentace ESRI se nachází zde: http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/Add_in_coding_patterns/0001000000zz000000/

Zde je fragment kódu z OnClick- Událost tlačítka ve vlastním formuláři:

//DESCRIPTION: //Connect a tool embedded in a Windows Form with the ArcGIS Application Framework. ESRI.ArcGIS.esriSystem.IUID UIDCls = new ESRI.ArcGIS.esriSystem.UIDClass(); UIDCls.Value = "MyNamespace_MyCustomTool"; IDocument actDoc = (IDocument)ArcMap.Document; //Finding the customTool ESRI.ArcGIS.Framework.ICommandItem commandItem = actDoc.CommandBars.Find(UIDCls, false, false); if (commandItem == null) { return; } //This cast would fail: //MyCustomTool_Class actCustomTool2 = (MyCustomTool_Class)commandItem.Command; MyCustomTool_Class actCustomTool = AddIn.FromID<MyCustomTool_Class (ThisAddIn.IDs.MyCustomTool); actCustomTool.actFrm = this; ArcMap.Application.CurrentTool = commandItem; 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *