12


1

WPF ListBox - SelectedItemの代わりにUIElementを取得する

Itemtemplate`として DataTemplate`を持つ ListBox`を作成しました。 しかし、コードビハインドで `SelectedItem`の代わりに生成された UIElement`にアクセスする簡単な方法はありますか?

SelectedItem`にアクセスするとき、私は自分の ItemsSource`コレクションから選択されたオブジェクトを取得するだけです。 `UIElement`にアクセスする方法はありますか バインドされたオブジェクトと一緒に `DataTemplate`から生成された要素)

2 Answer


13


あなたはhttp://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemcontainergenerator.aspx[ItemContainerGenerator]プロパティを探しています。 各 `ItemsSource`はhttp://msdn.microsoft.com/en-us/library/system.windows.controls.itemcontainergenerator.aspx[ItemContainerGenerator]インスタンスを持ちます。 このクラスには、興味があるかもしれない以下のメソッドがあります。http://msdn.microsoft.com/en-us/library/system.windows.controls.itemcontainergenerator.containerfromitem.aspx[ContainerFromItem(object instance)]]。

`ListBoxItem`へのハンドルを取得したら、先に進んで論理ツリーとビジュアルツリーを閲覧することができます。 Logical Tree Helperおよびhttp://msdn.microsoft.com/en-us/library/system.windowsをチェックしてください。 .media.visualtreehelper.aspx [ビジュアルツリーヘルパー]

Andyがコメントで述べたように、あなたのコレクションに項目が存在するからといって、それに対してコンテナが生成されたという意味ではありません。 あらゆる種類の仮想化パネルのシナリオでこの問題が発生します。 UIElementはさまざまなアイテムにわたって再利用されます。 それにも注意してください。


4


sizAndy、および_Bodeaker_は絶対に正しいです。

これは、リストボックスの選択したアイテムのテキストボックスをそのハンドルを使用して取得する方法です。

FrameworkElementとしてvar container = listboxSaveList.ItemContainerGenerator.ContainerFromItem(listboxSaveList.SelectedItem)。 if(container!= null){ContentPresenter queueListBoxItemCP = VisualTreeWalker.FindVisualChild(container); if(queueListBoxItemCP == null)を返します。

DataTemplate dataTemplate = queueListBoxItemCP.ContentTemplate;

TextBox tbxTitle =(TextBox)dataTemplate.FindName( "tbxTitle"、queueListBoxItemCP); tbxTitle.Focus(); }

(注:ここで、VisualTreeWalkerは、さまざまな便利な機能を公開したVisualTreeHelperの上の私自身のラッパーです。)