2009-06-11 14 views
21

こんにちは私はitemscontrolのためのdatatemplate内の単一のテキストボックスを持っています。 itemcontrolsを観測可能なコレクションにバインドすると、2つのテキストボックスが表示されます。しかし、私はいくつかのIDを使用して各テキストボックスを別々に探したいテキストボックスに基づいていくつかの操作を行う必要があります。WPF itemscontrol内のコントロールを見つける

誰でもWPFのitemscontrolを使用してコントロールを見つける方法を手助けできますか?

+1

あなたは実行する必要がありますか? itemscontrolのすべての項目の中でテキストボックスを一意に識別するか、または2つだけを区別する必要がありますか? – Oskar

+0

こんにちはオスカー itemscontrol内にはラベルとテキストボックスしかありませんでした。私はテキストボックスコントロールのハンドルを一意に(いくつかのIDを使用して)取得する方法が必要です。 itemscontrolがロードされているときにテキストボックスにフォーカスを設定する必要があり、指定された時間にフォーカスがあるテキストボックスを特定して何らかの操作を実行する必要があります。 おかげ ディーパック おかげ ディーパック – deepak

+0

もっと単純にどのように私はC#を使用してのItemsControlコントロールコレクションを反復処理することができます。 – deepak

答えて

62

ItemContainerGeneratorを使用すると、生成された項目のコンテナを取得し、ビジュアルツリーを下方向にトラバースしてTextBoxを見つけることができます。 ItemsControlにのケースでは、のContentPresenterになりますが、あなたがしたい場合、リストボックスは

itemsControl.ItemContainerGenerator.ContainerFromIndex(0); 
を使用します。また、インデックスで、コンテナを得ることができ

ContentPresenter cp = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter; 
TextBox tb = FindVisualChild<TextBox>(cp); 
if (tb != null) 
{ 
    // do something with tb 
} 

public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject 
{ 
    if (depObj != null) 
    { 
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
      if (child != null && child is T) 
      { 
       return (T)child; 
      } 

      T childItem = FindVisualChild<T>(child); 
      if (childItem != null) return childItem; 
     } 
    } 
    return null; 
} 

ListBoxItem、リストビューのListViewItemなどを返します。

+0

ありがとうBryce – deepak

+0

答えとしてマークしてください。 –

+0

私はこのメソッドを使用していますが、私はコンストラクタでそれを呼び出しています。 (悪い考え?)とにかく、私はchild.ApplyTemplate()を呼び出さなければならなかった。静的リソースで定義されたテンプレートを持つ子供のためにビジュアルツリーを作成する。 –

2

VisualTreeHelperをお試しください。 ItemsControl自体のプロパティは、データを可視化するために使用されるテンプレートインスタンスではなく、バインドされたデータのみを取得することを許可します。VisualTreeHelperでは、WPFがレンダリングしたときにビジュアルツリーをブラウズできます。

親ItemControlの視覚的な子を(再帰的に)繰り返し処理する場合、画面に表示されているテキストボックスの位置を特定するのに問題はありません。

5

ありがとうブライス、私は上向きの矢印をチェックしようとしましたが、私の評価が低すぎると言います!ごめんなさい!

与えられた型のすべての子のリストをすべて返すようにコードを修正し、他の人がそれを役に立つと思ったと思った。

もう一度ブライス、本当に有用 - 評価の事を申し訳ありません!

public static List<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     List<T> list = new List<T>(); 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
       if (child != null && child is T) 
       { 
        list.Add((T)child); 
       } 

       List<T> childItems = FindVisualChildren<T>(child); 
       if (childItems != null && childItems.Count() > 0) 
       { 
        foreach (var item in childItems) 
        { 
         list.Add(item); 
        } 
       } 
      } 
     } 
     return list; 
    } 
+0

私は最近あなたがここでやろうとしていることのわずかなバリエーションを投稿しました:http://stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by-type –

+0

@Clarke:マイナーな修正 - それは 'childItems.Count()'ではなく 'childItems.Count'でなければなりません。 –

0

あなたは、次のコードサンプル

<DataGridTemplateColumn x:Name="photoPathColumn" Header="{x:Static resx:FrmResource.Photo}"> 
    <DataGridTemplateColumn.CellEditingTemplate x:Uid="keyelm"> 
     <DataTemplate x:Name="dodo"> 
      <StackPanel Orientation="Horizontal" Height="Auto"> 
       <TextBlock x:Name="photo" x:Uid="imageFile" Text="{Binding Path=PhotoPath}" /> 
       <Button x:Name="Browse" Content="..." Click="Browse_Click" /> 
      </StackPanel> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellEditingTemplate> 

photoPathColumn.CellEditingTemplate.FindName("photo",photoPathColumn.GetCellContent(CustomersDataGrid.CurrentItem)) 
1

別の例を使用することができます 、データテンプレートが含まれているデータグリッドとテンプレート列を、持っている場合:行う操作はどんな

private void DataGridBank_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) 
    { 
     try 
     {  
      switch (e.Key) 
      { 
       case Key.Down: 

        if ((DataGridBank.SelectedIndex + 1) <= DataGridBank.Items.Count) 
        { 
         DataGridBank.SelectedIndex = DataGridBank.SelectedIndex + 1; 
         FocusCell(); 
        } 
        break; 

       case Key.Up: 

        if ((DataGridBank.SelectedIndex - 1) >= 0) 
        { 
         DataGridBank.SelectedIndex = DataGridBank.SelectedIndex - 1; 
         FocusCell(); 
        } 
        break; 

       case Key.Enter: 
       case Key.Tab: 
        FocusCell();     

        break; 
      } 
     } 
     catch (Exception ex) 
     { 

     } 
    } 


    private void DataGridBank_Loaded(object sender, RoutedEventArgs e) 
    { 
     try 
     { 
      if (DataGridBank.Items.Count > 0) 
      { 
       DataGridBank.SelectedIndex = 0; 

       FocusCell(); 
      } 

     }catch(Exception ex) 
     { 

     } 
    } 


    private void FocusCell() 
    { 
     var selectedRow = (DataGridRow)DataGridBank.ItemContainerGenerator.ContainerFromItem(DataGridBank.SelectedItem); 

     var textImport = FindVisualChild<TextBox>(selectedRow); 
     textImport.Focus(); 
     textImport.SelectAll(); 
    } 


    public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
       if (child != null && child is T) 
       { 
        return (T)child; 
       } 

       T childItem = FindVisualChild<T>(child); 
       if (childItem != null) return childItem; 
      } 
     } 
     return null; 
    } 
関連する問題