2015-10-13 35 views
5

WPF的新增功能,对WinForms非常适用(可能会使转换更加粗糙)。我试图将一个旧的WinForms项目的一些功能作为学习体验移植到WPF中。WPF Datagrid循环通过/选择具有特定属性的单元格

目标是在与TextBox中的字符串匹配的DataGrid中查找单元格值。我发现一个great example使用绑定,将做到这一点。基本上链接的代码会将任何匹配的DataGridCell的背景颜色更改为橙​​色。我修改了我的版本,但功能应该是一样的。请参阅代码示例的链接,在这里提供它似乎有点多余。填充DataGrid的数据来自DataTable(如果有的话)。

我想从那里做的是有一个“下一步”按钮,将循环通过每个单元格(通过使用背景颜色或自定义属性DataGridTextSearch.IsTextMatch确定)并选择它。似乎有可能只是修改提供的代码,但我不知道从哪里开始。在我旧的WinForms项目中,我将DataGridViewCell存储在一个列表中(在查找Linq查询后),并附加按钮行为以增加所述列表并设置当前单元格。我怀疑可能有一个更聪明/更好的绑定方式,如果这是一个选项,我甚至不知道如何将这些匹配的单元添加到列表中。总而言之,我想要一个循环遍历特定DataGridCells(基于Background或自定义DataGridTextSearch.IsTextMatch属性)并选择它们的按钮。

在此先感谢。

回答

5

根据您在问题中提供的link,我已经为此解决了问题。在当DataGridCellTextBox字符串匹配我的解决方案,这是Tag属性将被设置为“1”,然后Button被点击时,它会通过所有DataGridCells迭代,并找到非空Tags项目终于显现细胞将逐一关注。

这里是工作的例子给你一个想法:

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

方法来获得突出的单元格:

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

令人惊叹。实际上,我正在做类似的工作,但是我会永远拿出整个解决方案。欣赏它!谢谢。 – Finch042

+0

非常欢迎你:) –

相关问题