Estoy creando una utilidad para ejecutar en ArcGIS for Desktop usando ArcObjects (9.3.1 SDK) y C # .Net. Mi prototipo implica una barra de herramientas con dos cuadros combinados y una herramienta. El primer combo selecciona una capa en la tabla de contenido, y el segundo selecciona un campo de la capa seleccionada. La herramienta se usará para interactuar con el mapa.
Básicamente quiero seleccionar una capa, seleccionar un campo válido, luego hacer clic en una entidad en el mapa y obtener su valor para el campo elegido. Aquí hay una imagen de la barra de herramientas, si ayuda:
[pregunta redactada casi por completo de aquí abajo]
El problema que tengo es pasar el estado entre las partes nativas de la interfaz de usuario de COM y mis controles personalizados .Net. Por ejemplo, quiero capturar el evento DropDownClosed en el cuadro combinado Capa, armar una lista válida de columnas relativas a esa capa, luego aplicar la lista de nombres de campo (a través de IFields) al cuadro combinado Campos.
Después de aplicar algunos de los comentarios iniciales de RagiYaserBurham y blah238, y fusionarlos con los detalles de esta página , el siguiente controlador de eventos DropDownClosed regresa del cuadro combinado a la barra de herramientas (ICommandBar), pero no entiendo cómo transmitir desde ICommandItem a mi implementación del cuadro combinado Campos en un 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);
}
Entonces ... ahora que estoy aquí ... ¿cómo lanzo fieldsItem a FieldSelectUC?
[ La solución ]
Como sugirió blah238, intenté enviar ICommandItem.Command a mi implementación personalizada de UserControl y eso funcionó.
Primero, tuve que agregar un descriptor de acceso público a mi FieldSelectUC
UserControl para devolver una referencia a su ComboBox; ese simple descriptor de acceso se ve así:
// fieldSelectCBO is the name of the combobox control in the design view..
public ComboBox FieldsComboBox { get { return fieldSelectCBO; } }
Con esa modificación en su lugar, aquí hay un controlador de eventos DropDownClosed que completará el cuadro combinado Campos con todos los campos de la capa seleccionada:
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!");
}
}
Esto sigue siendo un banco de pruebas sucio (de ahí AngryToolbar). Pero la solución muestra cómo comenzar desde un UserControl extendido que implementa ICommand e IToolControl y volver a un componente .Net. Realmente aprecio la ayuda de todos los que ofrecieron sugerencias. Muchas gracias. :)