ArcObjects (ArcGIS for Desktop és C #): Hogyan lehet átvetni az ArcMap COM felhasználói felület és az egyéni .Net UserControl objektumok között?

Létrehozok egy segédprogramot az ArcGIS for Desktop futtatásához ArcObjects (9.3.1 SDK) és C # .Net használatával. A prototípusom egy eszköztárat tartalmaz két comboboxok és egy eszköz. Az első kombó kiválaszt egy réteget a TOC-ben, a második pedig egy mezőt a kiválasztott rétegből. Az eszközt a térképpel való interakcióra használják.

Alapvetően egy réteget, válasszon ki egy érvényes mezőt, majd kattintson egy elemre a térképen, és szerezze be annak értékét a kiválasztott mező számára. Itt van egy kép az eszköztárról, ha az segít:

ide írja be a kép leírását

[a kérdés szinte teljesen át van formázva innen lefelé]

A problémám az állapot átvitele a natív COM felhasználói felület részei és az egyéni .Net vezérlők között. Például el akarom fogni a DropDownClosed eseményt a Layer kombinációs dobozon, összeállít egy érvényes oszloplistát a fóliához képest, majd alkalmazom a mezők nevének listáját (IFields-en keresztül) a Fields kombinációs dobozra. alkalmazva a RagiYaserBurham és a blah238 kezdeti megjegyzéseit, és egyesítve őket ezen oldal részleteivel, a következő DropDownClosed eseménykezelő a comboboxból visszamegy az eszköztárba ( ICommandBar), de nem értem, hogyan lehet átküldeni az ICommandItem-ről a Fields combobox implementációjához egy UserControl-ban:

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); } 

Tehát .. most Itt vagyok .. hogyan vethetem a FieldItem elemet a FieldSelectUC fájlba?

[ A megoldás ]

Ahogy a blah238 javasolta, megpróbáltam átküldeni az ICommandItem.Command-ot az egyedi UserControl implementációmnak, és ez megcsinálta a trükköt.

Először hozzá kellett adnom egy nyilvános hozzáférést a FieldSelectUC UserControl-hoz, hogy visszatérést adjak a ComboBox-ba; ez az egyszerű hozzáférés így néz ki:

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

Ha ez a módosítás helyben van, akkor itt egy DropDownClosed eseménykezelő, amely feltölti a Fields comboboxot a kiválasztott réteg:

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!"); } } 

Ez még mindig piszkos tesztasztal (tehát az AngryToolbar). De a megoldás megmutatja, hogyan lehet elindulni egy kiterjesztett UserControl-ból, amely az ICommand és az IToolControl és térjen vissza egy .Net komponensre. Nagyon értékelem mindenki segítségét, aki javaslatokat tett. Köszönöm szépen. 🙂

Megjegyzések

  • Hogyan arról, hogy a layerName változó nyilvános, statikus hatókörűvé válik-e?
  • @ artwork21, ez jól hangzik, de még mindig nem vagyok biztos abban, id = “f9316bd63b”>

megfelelője az eszköztáron? Tudja, mire gondolok? Gyanítom, hogy ‘ egy egyszerű alapvető dolog, amiről én ‘ nem tudok.

  • Ez különbségnek hangzik kérdés. ‘ Nem tudom, miért kell ezt tennie. Számomra úgy tűnik, hogy a Fields komboboxot ki kell törölni és újratelepíteni a Layer kombó alapján. A Layer kombinációs mezőt a dokumentumesemény-figyelő alapján kell feltölteni.
  • @RichWawrzonek pontosan ez a helyes. De ‘ nem vagyok biztos abban, hogyan juthatok el a Fields kombó meglévő példányához a Rétegek kombinációból. Ehhez az eszköznek el kell olvasnia mindkét értéküket.
  • Válasz

    Mint megértettem, két .NET ComboBox van egy UserControl-on, amely az ICommand és az IToolControl végrehajtását végzi, és hivatkozást szeretne kapni az egyik kombinációs mezőre a másiktól. Amíg ugyanabban a körben vannak, csak a változó nevükön kell hivatkozni rájuk (ellenőrizze a kezelőszervek nevét a UserControl tervezőjében).

    Ha a két kombinációs mező külön van UserControls, majd próbálja átküldeni az ICommandItem.Command elemet a másik UserControl parancsra.

    Néhány példa: 9 div súgó: Legutóbb használt fájlok – Command, MultiItem és ToolControl

    Itt található egy ESRI fórumbejegyzés is, amely a problémát tárgyalja: http://forums.esri.com/Thread.asp?c=93&f=993&t=170088

    Megjegyzések

    • Bingó. Ez a sor trükközött, hogy a ICommandItem példányból visszakerüljön az általam megvalósított UserControl osztályba: FieldSelectUC fs = fieldsItem.Command as FieldSelectUC; Most már látom az összes ‘ kellékét a hibakeresőben. Óriási köszönet neked.
    • Hurrá! ‘ Egy ideje kizárólagosan használom a bővítményeket, ezért át kellett ásnom néhány régi dolgot, hogy emlékezzek az egész működésére 🙂 Ez a fajta dolog sokkal könnyebb (bár igaz kevésbé rugalmas) 10-es bővítményekkel, mivel létezik egy speciális ComboBox típus, és csak statikus változókkal és módszerekkel hivatkozhat más kiegészítő összetevőkre.
    • Igen, az új kiegészítők révén mindenképpen könnyebbnek tűnt. Ennek kutatása során találtam ezt és azokat a bővítményeket, amelyek azonban csak ‘ nem elérhetőek a megvalósításom számára. A .Net súgóban szereplő GraphicsLayerToolControl példa (a rendszeremen ez a cím C:\Program Files (x86)\ArcGIS\DeveloperKit\SamplesNET\Desktop\GraphicsLayerToolControl\CSharp\GraphicsLayerToolControl2008.sln), amely segített elindulni a UserControl és események cuccai között, de ‘ ne találja ki, hogyan lehet a COM vezérlőből lyukat ütni a .Net felé. ‘ nem tudom eltúlozni, hogy mennyire hálás vagyok. Üdvözlettel.

    Válasz

    Valahányszor ilyesmit csinálok, a réteg és mező nevét statikusan tárolom az eszköztáron található tulajdonságkészlet. Ezután egy dokumentumesemény-kezelővel ellenőrizem, hogy vannak-e rétegek hozzáadva / eltávolítva az ArcMap-ból, vagy megváltozott-e a dokumentum. A réteg és a mező tulajdonságai frissülnek, amikor a felhasználó megváltoztatja azokat a legördülő menüben. Ha a fólia eltávolításra kerül az ArcMap-ból, vagy a dokumentum bezárul, akkor azok nullára lesznek állítva. Ezután csak ellenőrizheti a null értékeket, mielőtt a program fut.

    Kérjen referenciát a comboboxra az ICommandItem felületen keresztül:

    ICommandItem toolbar = _iApp.Document.CommandBars.Find (“ArcProject.UI.AngryToolbar”, false, false);
    ICommandItem fieldsItem = (eszköztár mint ICommandBar) .Find (“ArcProject.UI.FieldSelectUC”, hamis); IComboBox cbo = (IComboBox) fieldsItem; // Hivatkozásra van szükség az ESRI.ArcGIS.SystemUI;

    Megjegyzések

    • +1 segítségével ilyen egyszerűen hangzik. 🙂 De az a problémám van, hogy bármilyen más vezérlés szempontjából hozzáférjek egy már példányos vezérlő tulajdonságaihoz. Tetszik az ötleted, miszerint a megosztott tulajdonságokat helyezik el az eszköztáron, frissítenéd a válaszodat, hogy megmutassam, hogyan tudom valójában elolvasni a benne lévő eszköztár tulajdonságait az egyik kombobox szempontjából? ‘ Mert ‘ alapvetően az, amit én ‘ m követek. Már tudom, hogyan kell használni a dokumentumeseményeket a TOC változásainak meghallgatásához, ezért nincs szükségem segítségre ebben a szempontban.

    Köszönjük válaszát.

  • @elrobis A megosztott állapotot magába az ICommand-ba is beillesztheti (mivel mindig csak egy példány lesz), és ezután a vezérlők kezelhetik a parancsot a help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/…
  • Ragi is jobb. Mivel a COM eszköztárat használja, egyszerűen átadhatja a combobox uid-ját az ICommandBar.Find metódusnak a referencia megszerzéséhez. Linkje mindent megmagyaráz.
  • Nekem is tetszik Ragi ‘ ötlete. Van valami, ami hiányzik nekem. Például ez a sor egy null eszköztárat ad vissza (ahol a this egy UserControl címkével és komboboxmal): ICommandBar toolbar = this.Parent as ICommandBar; Ez ‘ ez a fajta alapvető felhasználói felület objektum bejárása, amely megöl. Nem tudom, hogy ‘ hogyan juthatnék vissza az eszköztárra egyik javaslatod végrehajtásához. (És valójában egy kicsit jobban tetszik ezeknek a változatoknak az eszköztáron ötlete. Én ‘ d valószínűleg úgy teszem, hogy nyilvános gettert adok az eszköztárhoz, amely alkalmazza a Ragi ‘ s ötlet). Köszönöm a folyamatos segítséget.
  • Nem gondolom, hogy ‘ nem gondolom, hogy a this.Parent a COM interfészekre érvényes – vagyis .NET / Windows Forms koncepció. Nem ‘ nem akarja ” átmenni a felhasználói felületen “, hozzáférni szeretne a IC-parancsok azonosítójuk szerint.
  • Válasz

    Hasonló problémám volt egy egyéni eszközzel. Van egy egyéni űrlapom, amelyet az ArcGis 10.x AddIn-Eszköztárának egyik gombja nyit meg. Ezen az űrlapon található egy gomb, amelynek vissza kell kapnia egy kattintás koordinátáit a térképen, bepattanva. Elindíthattam az eszközt, és kezelhettem a kattintást a térképen, de az értéket nem tudtam visszakapni az űrlapomhoz, mert az egyéni eszközre történő átküldés mindig nem sikerült. A megoldás az volt, hogy az ESRI.ArcGIS.Desktop.AddIns fájlt használja az AddIn használatával. Ezzel könnyű volt hozzáférni az egyedi eszköz minden tulajdonságához és metódusához. Az ESRI dokumentáció itt található: http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/Add_in_coding_patterns/0001000000zz000000/

    Itt található az OnClick- A gomb eseménye az egyéni űrlapon:

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

    Vélemény, hozzászólás?

    Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük