2009-06-11 13 views
21

Ciao, ho una piccola casella di testo all'interno del datatemplate per itemscontrol. Quando lego gli itemcontrols ad una collezione osservabile ottengo due caselle di testo. Ma ho bisogno di fare alcune manipolazioni basate su ciascuna delle caselle di testo per le quali voglio trovare separatamente ciascuna casella di testo usando un id.Ricerca del controllo all'interno di WPF itemscontrol

Qualcuno può aiutarmi su come trovare un controllo witin ItemsControl in WPF.

+1

Che tipo di manipolazione fare hai bisogno di esibirti? Hai bisogno di identificare le caselle di testo in modo univoco tra tutti gli oggetti del controllo items o solo per separare i due gli uni dagli altri? – Oskar

+0

Ciao Oscar Ho avuto solo etichette e caselle di testo all'interno del mio itemscontrol. Ho bisogno di un modo per ottenere l'handle per il controllo della casella di testo in modo univoco (usando qualche id). La necessità di base di mettere a fuoco la casella di testo quando viene caricato il controllo items e di identificare quale delle caselle di testo ha lo stato attivo in un dato momento ed eseguire alcune operazioni. Grazie Deepak Grazie Deepak – deepak

+0

Più semplicemente come posso scorrere sulla raccolta di controllo itemscontrol utilizzando C#. – deepak

risposta

62

Utilizzando l'ItemContainerGenerator è possibile ottenere il contenitore generato per una voce e attraversare i verso il basso albero visuale per trovare il tuo TextBox. Nel caso di un ItemsControl sarà un ContentPresenter, ma un ListBox restituirà una ListBoxItem, ListView un ListViewItem, ecc

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; 
} 

È possibile anche ottenere il contenitore indice se si desidera utilizzando

itemsControl.ItemContainerGenerator.ContainerFromIndex(0); 
+0

Grazie mille Bryce – deepak

+0

Puoi contrassegnare come risposta per favore? –

+0

Sto usando questo metodo, ma lo sto chiamando nel costruttore. (cattiva idea?) In ogni caso, ho dovuto chiamare child.ApplyTemplate(); per far sì che l'albero visivo si riempia per i bambini con modelli definiti in risorse statiche. –

2

si consiglia di provare a utilizzare VisualTreeHelper. Le proprietà su ItemsControl consentiranno solo di ottenere i dati a cui sono associati, non le istanze del modello utilizzate per visualizzare i dati, mentre VisualTreeHelper consente di esplorare l'albero visivo come WPF lo ha reso.

Se si scorre attraverso il genitore bambini visivi di ItemControl (ricorsivamente), non si dovrebbe avere alcuna difficoltà a individuare le caselle di testo che state vedendo sullo schermo.

5

Grazie Bryce, ho provato a spuntare la freccia su ma dice che la mia valutazione è troppo bassa! Scusate!

ho modificato il codice per restituire tutto un elenco di tutti i figli di un dato tipo come era quello che mi serviva e ho pensato qualcun altro possa essere utile.

Grazie ancora Bryce, davvero utile - mi dispiace per la valutazione!

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

Recentemente ho pubblicato una leggera variazione di ciò che stai cercando di fare qui: http://stackoverflow.com/questions/974598/find-all-controls-in-wpf-window-by-type –

+0

@Clarke: una piccola soluzione - dovrebbe essere 'childItems.Count' invece di' childItems.Count() '. –

0

Se si dispone di griglia di dati e la colonna modello, che contiene modello di dati, è possibile utilizzare il seguente codice di esempio

<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

Un altro esempio:

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; 
    } 
Problemi correlati