ArcObjects (ArcGIS for Desktop og C #): Hvordan kaste du mellom ArcMap COM UI og mine egendefinerte .Net UserControl-objekter?

Jeg oppretter et verktøy som skal kjøres i ArcGIS for Desktop ved hjelp av ArcObjects (9.3.1 SDK) og C # .Net. Prototypen min innebærer en verktøylinje med to kombinasjonsbokser og et verktøy. Den første kombinasjonen velger et lag i innholdsfortegnelsen, og det andre velger et felt fra det valgte laget. Verktøyet skal brukes til å samhandle med kartet.

I utgangspunktet vil jeg velge en lag, velg et gyldig felt, og klikk deretter på en funksjon på kartet og få verdien for det valgte feltet. Her er et bilde av verktøylinjen, hvis det hjelper:

skriv inn bildebeskrivelse her

[spørsmål nesten omformulert herfra og ned]

Problemet jeg har er å passere tilstand mellom de opprinnelige COM UI-delene og de egendefinerte .Net-kontrollene mine. For eksempel vil jeg fange DropDownClosed-hendelsen på Layer-kombinasjonsfeltet, sette sammen en gyldig liste over kolonner i forhold til det laget, og deretter bruke listen over feltnavn (via IFields) i feltfeltet.

Etter ved å bruke noen av de første kommentarene fra RagiYaserBurham og blah238, og slå dem sammen med detaljer fra denne siden , går den følgende DropDownClosed-hendelsesbehandleren fra kombinasjonsboksen tilbake til verktøylinjen ICommandBar), men jeg forstår ikke hvordan jeg skal kaste fra ICommandItem tilbake til implementeringen av Fields-kombinasjonsboksen i en 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); } 

Så .. nå at Jeg er her .. hvordan kaster jeg feltItem til FieldSelectUC?

[ Løsningen ]

Som blah238 foreslo, prøvde jeg å kaste ICommandItem.Command til min egendefinerte UserControl-implementering, og det gjorde susen.

Først måtte jeg legge til en offentlig tilgang til FieldSelectUC UserControl for å returnere en referanse til ComboBox; den enkle tilgangen ser slik ut:

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

Med den endringen på plass, her «en DropDownClosed-hendelsesbehandler som vil fylle ut feltkombinasjonen med alle feltene i valgt lag:

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

Dette er fremdeles en skitten testbed (derav AngryToolbar). Men løsningen viser hvordan du starter fra en utvidet UserControl som implementerer ICommand og IToolControl og bor tilbake til en .Net-komponent. Jeg setter stor pris på hjelpen fra alle som ga forslag. Tusen takk. 🙂

Kommentarer

  • Hvordan om å gjøre din layerName-variabel offentlig statisk omfang?
  • @ artwork21, det høres bra ut, men jeg ‘ er fortsatt ikke sikker på hvordan jeg får tilgang til forekomsten av noen kombinasjonsfelt dens motstykke på verktøylinjen? Vet du hva jeg mener? Jeg mistenker at det ‘ er en enkel grunnleggende ting jeg ‘ jeg bare ikke er klar over.
  • Dette høres ut som en forskjell spørsmål. Jeg ‘ er ikke klar over hvorfor du trenger å gjøre det. Det ser ut til at feltfeltet skal tømmes og fylles ut på nytt basert på Layer-kombinasjonen. Layer-kombinasjonsfeltet bør fylles ut basert på lytteren for dokumenthendelsen.
  • @RichWawrzonek det er helt riktig. Men jeg ‘ er ikke sikker på hvordan jeg kommer til den eksisterende forekomsten av feltkombinasjonen fra lagkombinasjonen. For den saks skyld må verktøyet lese begge verdiene.

Svar

Som jeg forstår det, har du to .NET ComboBoxes på en UserControl som implementerer ICommand og IToolControl, og du vil få en referanse til en av kombinasjonsboksene fra den andre. Så lenge de er i samme omfang, bør du bare kunne henvise til dem ved hjelp av variabelnavnene (sjekk UserControl-designeren for navnene på kontrollene dine.).

Hvis de to kombinasjonsfeltene er på separate UserControls, og prøv deretter å kaste ICommandItem.Command til den andre UserControl.

Se dette eksemplet i 9.3-hjelpen for noen eksempler: Nylig brukte filer – Command, MultiItem og ToolControl

Også her er et ESRI-foruminnlegg som diskuterer dette problemet: http://forums.esri.com/Thread.asp?c=93&f=993&t=170088

Kommentarer

  • Bingo. Denne linjen gjorde susen for å komme fra forekomsten av ICommandItem tilbake til UserControl klasse jeg implementerte: FieldSelectUC fs = fieldsItem.Command as FieldSelectUC; Jeg kan nå se alt det ‘ s rekvisitter i feilsøkingsprogrammet. Stor takk til deg.
  • Hurra! Jeg ‘ har brukt tillegg eksklusivt en stund, så jeg måtte grave gjennom noen gamle ting for å huske hvordan det hele fungerte 🙂 Denne typen ting er mye lettere (skjønt riktignok mindre fleksibel) med tillegg i 10 siden det er en spesifikk ComboBox-type, og du kan bare referere til andre tilleggskomponenter med statiske variabler og metoder.
  • Ja, det virket definitivt lettere gjennom de nye tilleggene. Når jeg undersøkte dette, fant jeg tillegg dette og tillegg som de bare var ‘ t tilgjengelig for implementeringen min. GraphicsLayerToolControl-eksemplet i .Net-hjelpen (på systemet mitt er adressen C:\Program Files (x86)\ArcGIS\DeveloperKit\SamplesNET\Desktop\GraphicsLayerToolControl\CSharp\GraphicsLayerToolControl2008.sln) som hjalp meg med å komme i gang med UserControl og hendelser, men jeg kunne bare ikke ‘ t å finne ut hvordan du kan slå et hull til .Net fra COM-kontrollen. Jeg kan ‘ t overdrive hvor takknemlig jeg er. Med vennlig hilsen.

Svar

Når jeg gjør denne typen ting, lagrer jeg lag- og feltnavnene i en statisk egenskapssett som finnes i verktøylinjen. Så bruker jeg en dokumenthendelsesbehandler for å sjekke om lag er lagt til / fjernet fra ArcMap eller om dokumentet endres. Lag- og feltegenskapene blir oppdatert når de endres i rullegardinmenyen av brukeren. Hvis laget fjernes fra ArcMap eller dokumentet lukkes, tilbakestilles det til null. Så kan du bare se etter nullverdier før programmet kjøres.

Få en referanse til kombinasjonsboksen gjennom ICommandItem-grensesnittet:

ICommandItem-verktøylinje = _iApp.Document.CommandBars.Find («ArcProject.UI.AngryToolbar», false, false);
ICommandItem fieldsItem = (verktøylinje som ICommandBar) .Find («ArcProject.UI.FieldSelectUC», false); IComboBox cbo = (IComboBox) feltItem; // Trenger en referanse til ESRI.ArcGIS.SystemUI;

Kommentarer

  • +1 du får det til å høres så enkelt ut. 🙂 Men problemet jeg har er å få tilgang til egenskapene til en allerede instansert kontroll fra et hvilket som helst annet kontrollperspektiv. Jeg liker ideen din om å plassere deres delte egenskaper på verktøylinjen. Kan du oppdatere svaret ditt for å vise hvordan jeg faktisk kan lese egenskapene til den inneholder verktøylinjen fra en av kombinasjonskassene? ‘ Cos at ‘ er i utgangspunktet det jeg ‘ m etter. Jeg vet allerede hvordan jeg bruker dokumenthendelser for å lytte etter endringer i innholdsfortegnelsen, så jeg trenger ikke ‘ ikke hjelp til det aspektet. Takk for svaret.
  • @elrobis Du kan også sette den delte tilstanden i selve IC-kommandoen (siden det alltid bare vil være en forekomst) og deretter få kontrollene til å håndtere kommandoen gjennom help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/…
  • Ragi er Ikke sant. Siden du bruker COM-verktøylinjen, kan du bare overføre bruken av kombinasjonsboksen til ICommandBar.Find-metoden for å få en referanse. Koblingen hans forklarer alt.
  • Jeg liker også Ragi ‘. Det er imidlertid noe grunnleggende jeg mangler. For eksempel returnerer denne linjen en null verktøylinje (der this er en UserControl med etikett og kombinasjonsfelt): ICommandBar toolbar = this.Parent as ICommandBar; Det er ‘ denne typen grunnleggende UI-objektgjennomgang som dreper meg. Jeg vet ikke ‘ hvordan jeg kommer tilbake til verktøylinjen for å implementere et av forslagene dine. (Og faktisk liker jeg ideen om disse varsene på verktøylinjen litt bedre. Jeg ‘ d gjør det sannsynligvis ved å legge til en offentlig getter i verktøylinjen som bruker Ragi ‘ sin idé). Takk for din fortsatte hjelp.
  • Jeg tror ikke ‘ t tror this.Parent er gyldig for COM-grensesnitt – altså et .NET / Windows Forms-konsept. Du vil ikke ‘ » krysse brukergrensesnittet «, du vil få tilgang til IC-kommandoer etter ID.

Svar

Jeg hadde et lignende problem med et tilpasset verktøy. Jeg har et tilpasset skjema som åpnes med en knapp på en AddIn-Toolbar i ArcGis 10.x. På dette skjemaet er det en knapp som skal hente koordinatene til et klikk på kartet, inkludert snapping. Jeg kunne starte verktøyet og håndtere klikket på kartet, men jeg kunne ikke få verdien tilbake til skjemaet mitt, fordi rollebesetningen til det tilpassede verktøyet alltid mislyktes. Løsningen var å bruke AddIn fra ESRI.ArcGIS.Desktop.AddIns. Med dette var det enkelt å få tilgang til alle eiendommer og metoder for mitt tilpassede verktøy. ESRIs-dokumentasjonen ligger her: http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/Add_in_coding_patterns/0001000000zz000000/

Her er kodebiten fra OnClick- Hendelse av knappen på det tilpassede skjemaet:

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

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *