Estou criando um utilitário para executar no ArcGIS for Desktop usando o ArcObjects (9.3.1 SDK) e o C # .Net. Meu protótipo envolve uma barra de ferramentas com duas caixas de combinação e uma ferramenta. O primeiro combo seleciona uma camada no sumário e o segundo seleciona um campo da camada selecionada. A ferramenta será usada para interagir com o mapa.
Basicamente, quero selecionar uma camada, selecionar um campo válido, clicar em um recurso no mapa e obter seu valor para o campo escolhido. Aqui está uma imagem da barra de ferramentas, se ajudar:
[pergunta quase inteiramente reformulada daqui em diante]
O problema que estou tendo é passar o estado entre as partes da interface do usuário COM nativa e meus controles .Net personalizados. Por exemplo, quero capturar o evento DropDownClosed na caixa de combinação Layer, montar uma lista válida de colunas em relação a essa camada e aplicar a lista de nomes de campos (via IFields) à caixa de combinação Fields.
Após aplicar alguns comentários iniciais de RagiYaserBurham e blah238 e mesclá-los aos detalhes desta página , o seguinte manipulador de eventos DropDownClosed vai da caixa de combinação de volta à barra de ferramentas (ICommandBar), mas não entendo como transmitir a partir de ICommandItem para minha implementação da caixa de combinação Fields em um 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);
}
Então .. agora que estou aqui .. como faço para converter fieldsItem para FieldSelectUC?
[ A solução ]
Como blah238 sugeriu, tentei converter ICommandItem.Command para minha implementação personalizada UserControl e isso foi o que fez.
Primeiro, tive que adicionar um acessador público ao meu FieldSelectUC
UserControl para retornar uma referência à sua ComboBox; esse acessador simples se parece com isso:
// fieldSelectCBO is the name of the combobox control in the design view..
public ComboBox FieldsComboBox { get { return fieldSelectCBO; } }
Com essa modificação, aqui está um manipulador de eventos DropDownClosed que preencherá a caixa de combinação Fields com todos os campos da camada selecionada:
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!");
}
}
Este ainda é um teste sujo (daí o AngryToolbar). Mas a solução mostra como iniciar a partir de um UserControl estendido que implementa ICommand e IToolControl e fazer drill down de volta para um componente .Net. Eu realmente aprecio a assistência de todos que ofereceram sugestões. Muito obrigado. :)