ArcObjects(9.3.1 SDK)とC#.Netを使用してArcGIS forDesktopで実行するユーティリティを作成しています。プロトタイプには2つのツールバーが含まれていますコンボボックスとツール。最初のコンボは目次のレイヤーを選択し、2番目のコンボは選択したレイヤーからフィールドを選択します。ツールはマップとの対話に使用されます。
基本的にはレイヤーで有効なフィールドを選択し、マップ内のフィーチャをクリックして、選択したフィールドの値を取得します。役立つ場合は、ツールバーの画像を次に示します。
[質問はここからほぼ完全に言い換えられます]
私が抱えている問題は、ネイティブCOMUIパーツとカスタム.Netコントロールの間で状態を渡すことです。たとえば、LayerコンボボックスでDropDownClosedイベントをキャッチし、そのレイヤーに関連する有効な列のリストを作成してから、フィールド名のリストを(IFieldsを介して)Fieldsコンボボックスに適用したいとします。
後RagiYaserBurhamとblah238による最初のコメントをいくつか適用し、それらをこのページの詳細とマージすると、次のDropDownClosedイベントハンドラーはコンボボックスからツールバーに戻ります( ICommandBar)ですが、ICommandItemからUserControlのFieldsコンボボックスの実装にキャストする方法がわかりません:
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); }
つまり、これで私はここにいます。fieldsItemをFieldSelectUCにキャストするにはどうすればよいですか?
[ソリューション]
blah238が示唆しているように、ICommandItem.CommandをカスタムUserControl実装にキャストしようとしましたが、それでうまくいきました。
まず、FieldSelectUC
UserControlにパブリックアクセサーを追加して、ComboBoxへの参照を返す必要がありました。その単純なアクセサーは次のようになります。
// fieldSelectCBO is the name of the combobox control in the design view.. public ComboBox FieldsComboBox { get { return fieldSelectCBO; } }
この変更を適切に行うと、ここに「Fieldsコンボボックスにすべてのフィールドを入力するDropDownClosedイベントハンドラー」が表示されます。選択したレイヤー:
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!"); } }
これはまだダーティなテストベッドです(したがってAngryToolbar)。しかし、ソリューションは、ICommandとIToolControlを実装する拡張UserControlから開始する方法を示しています。 .Netコンポーネントにドリルダウンします。提案を提供してくれたすべての人の支援に本当に感謝しています。どうもありがとう。:)
コメント
- 方法layerName変数をパブリック静的スコープにすることについて?
- @ artwork21、それは良さそうですが、’からどちらのコンボボックスのインスタンスにアクセスするかまだわかりませんツールバーの対応するものですか?意味がわかりますか?’私が’気づいていない単純な基本的なことだと思います。
- これは違いのように聞こえます誤った質問。 ‘なぜそうする必要があるのかわかりません。 Fieldsコンボボックスは、Layerコンボに基づいてクリアし、再入力する必要があるように思われます。レイヤーコンボボックスは、ドキュメントイベントリスナーに基づいて入力する必要があります。
- @RichWawrzonekまさにその通りです。しかし、’レイヤーコンボからフィールドコンボの既存のインスタンスにアクセスする方法がわかりません。さらに言えば、ツールは両方の値を読み取る必要があります。
回答
私が理解しているように、ICommandとIToolControlを実装するUserControlに2つの.NETComboBoxがあります。コンボボックスの1つへの参照を他から取得したい。それらが同じスコープ内にある限り、変数名でそれらを参照できるはずです(コントロールの名前については、UserControlデザイナを確認してください)。
2つのコンボボックスが別々にある場合UserControlsを選択してから、ICommandItem.Command
を他のUserControlにキャストしてみてください。
いくつかの例については、9.3ヘルプの次のサンプルを参照してください:最近使用されたファイル-Command、MultiItem、およびToolControl
また、この問題について説明しているESRIフォーラムの投稿もあります: http://forums.esri.com/Thread.asp?c=93&f=993&t=170088
コメント
- ビンゴ。この行は、
ICommandItem
のインスタンスから実装したUserControl
クラスに戻すためのトリックを行いました:FieldSelectUC fs = fieldsItem.Command as FieldSelectUC;
デバッガーですべての’の小道具を確認できるようになりました。本当にありがとうございました。 - やったー! ‘しばらくの間、アドインを排他的に使用していたので、すべてがどのように機能したかを思い出すために、古いものを掘り下げなければなりませんでした:)この種のことははるかに簡単です(確かに)特定のComboBoxタイプがあり、静的変数とメソッドを使用して他のアドインコンポーネントを参照できるため、10のアドインでは柔軟性が低くなります。
- うん、新しいアドインを使えば間違いなく簡単に見えた。これを調査したところ、アドインthisとアドインが見つかりましたが、’実装で使用できませんでした。 .NetヘルプのGraphicsLayerToolControlの例(私のシステムでは、アドレスは
C:\Program Files (x86)\ArcGIS\DeveloperKit\SamplesNET\Desktop\GraphicsLayerToolControl\CSharp\GraphicsLayerToolControl2008.sln
)で、UserControlやイベントを処理するのに役立ちましたが、’ COMコントロールから.Netに穴を開ける方法を理解します。 ‘私がどれほど感謝しているかを誇張することはできません。よろしくお願いいたします。
回答
このようなことを行うときは常に、レイヤー名とフィールド名を静的に保存しますツールバーに含まれるプロパティセット。次に、ドキュメントイベントハンドラーを使用して、レイヤーがArcMapに追加/削除されているかどうか、またはドキュメントが変更されているかどうかを確認します。レイヤーとフィールドのプロパティは、ユーザーがドロップダウンで変更するたびに更新されます。レイヤーがArcMapから削除されるか、ドキュメントが閉じられると、nullにリセットされます。次に、プログラムを実行する前にnull値をチェックできます。
ICommandItemインターフェイスを介してコンボボックスへの参照を取得します。
ICommandItemツールバー= _iApp.Document.CommandBars.Find( “ArcProject.UI.AngryToolbar”、false、false);
ICommandItem fieldsItem =(ICommandBarとしてのツールバー).Find( “ArcProject.UI.FieldSelectUC”、false); IComboBox cbo =(IComboBox)fieldsItem; //ESRI.ArcGIS.SystemUIへの参照が必要です;
コメント
- +1あなたはそれをとても簡単に聞こえるようにします。 :)しかし、私が抱えている問題は、他のコントロールの観点から、すでにインスタンス化されているコントロールのプロパティにアクセスすることです。共有プロパティをツールバーに配置するというあなたのアイデアが好きです。コンボボックスの1つの観点から、含まれているツールバーのプロパティを実際に読み取る方法を示すために、回答を更新できますか? ‘ ‘は、基本的に私が’後に行ったものです。ドキュメントイベントを使用して目次の変更をリッスンする方法をすでに知っているので、’その側面についてのヘルプは必要ありません。返信ありがとうございます。
- @elrobis共有状態をICommand自体に入れて(インスタンスは常に1つしかないため)、コントロールに
help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/ …
this
はラベルとコンボボックスを備えたUserControl
です):ICommandBar toolbar = this.Parent as ICommandBar;
‘は、私を殺しているこの種の基本的なUIオブジェクトトラバーサルです。 ‘ツールバーに戻っていずれかの提案を実装する方法がわかりません。 (実際、ツールバーのこれらの変数のアイデアの方が少し気に入っています。’おそらく、Ragi のアイデア)。今後ともよろしくお願いいたします。this.Parent
がCOMインターフェイスに有効だとは思いません。 .NET / Windowsフォームの概念。 ‘ ” UIをトラバースしたくない”、アクセスしたいIDによるICommands。回答
カスタムツールでも同様の問題が発生しました。 ArcGis10.xのアドインツールバーのボタンで開くカスタムフォームがあります。このフォームには、スナップを含めて、マップ内のクリックの座標を取得するボタンがあります。ツールを起動してマップ内のクリックを処理することはできましたが、カスタムツールへのキャストが常に失敗したため、値をフォームに戻すことができませんでした。解決策は、ESRI.ArcGIS.Desktop.AddInsのAddInを使用することでした。これにより、カスタムツールのすべてのプロパティとメソッドに簡単にアクセスできました。 ESRIのドキュメントは次の場所にあります: http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/Add_in_coding_patterns/0001000000zz000000/
OnClickのコードスニペットは次のとおりです-カスタムフォームのボタンのイベント:
//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;