2015-10-13 37 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

非常歡迎你:) –

相關問題