2015-10-13 15 views
5

Nuovo di zecca per WPF, piuttosto comodo con WinForms (che probabilmente sta rendendo la transizione più difficile). Sto cercando di trasferire alcune funzionalità da un vecchio progetto WinForms in WPF come esperienza di apprendimento.WPF Datagrid Cycle Through/Select Cells With Specific Property

L'obiettivo è trovare i valori di cella in un DataGrid che corrisponde a una stringa in un controllo TextBox. Ho trovato un great example usando i collegamenti che faranno esattamente questo. Fondamentalmente il codice collegato cambierà il colore di sfondo di qualsiasi DataGridCell corrispondente in arancione. Ho modificato la mia versione un po ', ma la funzionalità dovrebbe essere la stessa. Si prega di vedere il link per esempi di codice, sembra un po 'ridondante per fornirlo qui. I dati che popolano il mio DataGrid provengono da un DataTable (se questo è importante).

Quello che voglio fare da lì è avere un pulsante "successivo" che scorrerà ciclicamente attraverso ciascuna di quelle celle (determinata utilizzando il colore di sfondo o la proprietà personalizzata DataGridTextSearch.IsTextMatch) e selezionandolo. Sembra che sarebbe possibile modificare solo il codice fornito, ma non so da dove cominciare. Nel mio vecchio progetto WinForms ho archiviato il DataGridViewCell in un elenco (dopo averlo trovato con una query Linq) e ho semplicemente attaccato il comportamento del pulsante per incrementare detto elenco e impostare la cella corrente. Sospetto che ci sia probabilmente un modo più intelligente/migliore che coinvolge i binding e non so nemmeno come aggiungere queste celle corrispondenti a una lista se fosse un'opzione.

Quindi, per riassumere, voglio un pulsante che passa ciclicamente attraverso DataGridCells specifici (basati sulla proprietà Background DataGridTextSearch.IsTextMatch) e li seleziona.

Grazie in anticipo.

risposta

5

In base allo link fornito nella domanda, sono arrivato a una soluzione per questo. Nella mia soluzione quando uno DataGridCell corrisponde alla stringa nello TextBox, è Tag la proprietà sarà impostata su "1" e quindi quando si fa clic su Button, itererà attraverso tutti gli DataGridCells e troverà elementi con valore non nullo Tags e infine celle evidenziate sarà focalizzato uno per uno.

Ecco un esempio di lavoro per dare un'idea:

Xaml:

<Window Name="UI"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <StackPanel DataContext="{Binding ElementName=UI}" Grid.Row="0"> 
      <TextBox Name="SearchBox" TextChanged="SearchBox_TextChanged"/> 
      <DataGrid x:Name="grid" 
        m:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" 
        ItemsSource="{Binding TestData}" 
        SelectionUnit="Cell"> 
       <DataGrid.Resources> 
        <m:SearchValueConverter x:Key="SearchValueConverter" /> 
        <Style TargetType="{x:Type DataGridCell}"> 
         <Setter Property="m:DataGridTextSearch.IsTextMatch"> 
          <Setter.Value> 
           <MultiBinding Converter="{StaticResource SearchValueConverter}"> 
            <Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" /> 
            <Binding RelativeSource="{RelativeSource Self}" Path="(m:DataGridTextSearch.SearchValue)" /> 
           </MultiBinding> 
          </Setter.Value> 
         </Setter> 
         <Style.Triggers> 
          <Trigger Property="m:DataGridTextSearch.IsTextMatch" Value="True"> 
           <Setter Property="Background" Value="Orange" /> 
           <Setter Property="Tag" Value="1" /> 
          </Trigger> 
         </Style.Triggers> 
        </Style> 
       </DataGrid.Resources> 
      </DataGrid> 
     </StackPanel> 
     <Button Grid.Row="1" Click="Button_Click" Content="GoNext"/> 
    </Grid> 
</Window> 

MainWindow.cs:

int currentIndex = 0; 

private void SearchBox_TextChanged(object sender, TextChangedEventArgs e) 
{ 
    currentIndex = 0; 
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    var selectedCells = GetHighLightedCells(); 
    if (selectedCells.Count == 0) 
     return; 

    selectedCells[currentIndex].Focus(); 

    if (currentIndex == selectedCells.Count - 1) 
     currentIndex = 0; 
    else 
     currentIndex++; 
} 

metodi per ottenere celle evidenziate:

public List<DataGridCell> GetHighLightedCells() 
{ 
    List<DataGridCell> selectedCells = new List<DataGridCell>(); 
    foreach (DataGridRow rowContainer in GetDataGridRows()) 
    { 
     if (rowContainer != null) 
     { 
      DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer); 
      foreach (var col in grid.Columns) 
      { 
       DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(col.DisplayIndex); 
       if (cell == null) 
       { 
        grid.ScrollIntoView(rowContainer, col); 
        cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(col.DisplayIndex); 
       } 
       if (cell.Tag != null) 
       { 
        selectedCells.Add(cell); 
       } 
      } 
     } 
    } 
    return selectedCells; 
} 
public IEnumerable<DataGridRow> GetDataGridRows() 
{ 
    var itemsSource = grid.ItemsSource as IEnumerable; 
    if (null == itemsSource) yield return null; 
    foreach (var item in itemsSource) 
    { 
     var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; 
     if (null != row) yield return row; 
    } 
} 

public static T GetVisualChild<T>(Visual parent) where T : Visual 
{ 
    T child = default(T); 
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < numVisuals; i++) 
    { 
     Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
     child = v as T; 
     if (child == null) 
     { 
      child = GetVisualChild<T>(v); 
     } 
     if (child != null) 
     { 
      break; 
     } 
    } 
    return child; 
} 
+1

Incredibile. In realtà stavo lavorando a qualcosa su linee simili, ma mi avrebbe richiesto per sempre l'intera soluzione. Apprezzalo! Grazie. – Finch042

+0

Siete i benvenuti :) –