2016-06-10 132 views
0

我有多个DataGrids第一列有一个复选框,并且标题也有一个复选框。正如我们都看到的,我希望能够点击标题复选框并让它选中下面的所有复选框。WPF DataGrid - 在运行时修改视图滚动视图

<DataGrid x:Name="dgReportTypes_New" Margin="10,140,0,0" Height="175" VerticalAlignment="Top" HorizontalAlignment="Left" Width="216" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="False" MouseUp="DataGrid_MouseUp" KeyDown="DataGrid_KeyDown"> 
     <DataGrid.Columns> 
      <DataGridCheckBoxColumn IsReadOnly="True" Binding="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" ClipboardContentBinding="{x:Null}"> 
       <DataGridCheckBoxColumn.HeaderTemplate > 
        <DataTemplate> 
         <CheckBox x:Name="chkSelectAll" IsThreeState="True" Checked="DataGridHeader_Checked" Unchecked="DataGridHeader_Unchecked" Indeterminate="DataGridHeader_Indeterminate" /> 
        </DataTemplate> 
       </DataGridCheckBoxColumn.HeaderTemplate> 
      </DataGridCheckBoxColumn> 
      <DataGridTextColumn IsReadOnly="True" Binding="{Binding Description}" CanUserResize="False" Width="*" /> 
     </DataGrid.Columns> 
    </DataGrid> 

经过

private void DataGridHeader_Checked(object sender, RoutedEventArgs e) 
    { 
     DataGrid dg = SGT.Helpers.ControlHelpers.Generics.FindVisualParent<DataGrid>(sender as DependencyObject, typeof(DataGrid)); 
     for (int i = 0; i < dg.Items.Count; i++) 
     { 
      DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i); 
      CheckBox c = ControlHelpers.CheckBoxes.ToggleCheckBox(row, true); 
     } 
     e.Handled = true; 
    } 

未检查

private void DataGridHeader_Unchecked(object sender, RoutedEventArgs e) 
    { 
     DataGrid dg = SGT.Helpers.ControlHelpers.Generics.FindVisualParent<DataGrid>(sender as DependencyObject, typeof(DataGrid)); 
     for (int i = 0; i < dg.Items.Count; i++) 
     { 
      DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i); 
      CheckBox c = ControlHelpers.CheckBoxes.ToggleCheckBox(row, false); 
     } 
     e.Handled = true; 
    } 

不定

private void DataGridHeader_Indeterminate(object sender, RoutedEventArgs e) 
    { 
     ((CheckBox)sender).IsChecked = false; 
     e.Handled = true; 
    } 

切换

 public static CheckBox ToggleCheckBox(DataGridRow row, bool? overrideValue) 
     { 
      if (row == null) 
      { 
       return null; 
      } 
      CheckBox c = Generics.FindVisualChild<CheckBox>(row as DependencyObject, typeof(CheckBox)); 

      if (overrideValue != null) 
      { 
       c.IsChecked = overrideValue; 
      } 
      else 
      { 
       c.IsChecked = !c.IsChecked; 
      } 

      return c; 
     } 

     public static CheckBox ToggleCheckBox(object sender, MouseButtonEventArgs e, bool? overrideValue) 
     { 
      DataGridRow row = ItemsControl.ContainerFromElement((DataGrid)sender, e.OriginalSource as DependencyObject) as DataGridRow; 
      if (row == null) 
      { 
       return null; 
      } 
      CheckBox c = Generics.FindVisualChild<CheckBox>(row as DependencyObject, typeof(CheckBox)); 

      if (overrideValue != null) 
      { 
       c.IsChecked = overrideValue; 
      } 
      else 
      { 
       c.IsChecked = !c.IsChecked; 
      } 

      e.Handled = true; 
      return c; 
     } 

查找视觉

 public static T FindVisualChild<T>(DependencyObject parent, Type type) where T : DependencyObject 
     { 
      if (parent == null) 
       Debug.Print("Parent Null"); 

      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
      { 
       var child = VisualTreeHelper.GetChild(parent, i); 
       if (child.GetType() == type) 
       { 
        Debug.Print(child.ToString()); 
        return child as T; 
       } 
       else 
       { 
        T result = FindVisualChild<T>(child, type); 
        if (result != null) 
         return result; 
       } 
      } 
      return null; 
     } 

DataGrid中点击了

private void DataGrid_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     CheckBox c = ControlHelpers.CheckBoxes.ToggleCheckBox(sender, e, null); 
     ValidateCheckAll((DataGrid)sender); 
    } 

柄头复选框,当项目选中/取消

private void ValidateCheckAll(DataGrid grid) 
    { 
     //HeaderedContentControl 
     DataGridColumnHeadersPresenter hp = Helpers.ControlHelpers.Generics.FindVisualChild<DataGridColumnHeadersPresenter>(grid, typeof(DataGridColumnHeadersPresenter)); 
     CheckBox c = Helpers.ControlHelpers.Generics.FindVisualChild<CheckBox>(hp, typeof(CheckBox)); 

     c.Checked -= new RoutedEventHandler(DataGridHeader_Checked); 
     c.Unchecked -= new RoutedEventHandler(DataGridHeader_Unchecked); 
     c.Indeterminate -= new RoutedEventHandler(DataGridHeader_Indeterminate); 

     int counter = 0; 

     for (int i = 0; i < grid.Items.Count; i++) 
     { 
      DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(i); 
      //row.Item 
      if (row != null) 
      { 
       CheckBox ch = Helpers.ControlHelpers.Generics.FindVisualChild<CheckBox>(row, typeof(CheckBox)); 
       if (ch.IsChecked == true) 
       { 
        counter++; 
       } 
      } 
      Debug.Print(counter.ToString() + " of " + grid.Items.Count.ToString()); 
     } 


     if (counter == 0) 
     { 
      c.IsChecked = false; 
     } 
     else if (counter == grid.Items.Count) 
     { 
      c.IsChecked = true; 
     } 
     else 
     { 
      c.IsChecked = null; 
     } 

     c.Checked += new RoutedEventHandler(DataGridHeader_Checked); 
     c.Unchecked += new RoutedEventHandler(DataGridHeader_Unchecked); 
     c.Indeterminate += new RoutedEventHandler(DataGridHeader_Indeterminate); 

    } 

我有一切工作我预想的样子,直到..我得到了一个有可滚动数据的DataGrid。

问题:只有可见的复选框发生变化。我使用视觉效果来获得复选框,并略微理解为什么会发生这种情况。

问题:有没有办法将CheckBox的其余部分改为视图外?

+0

DataGridHeader_Checked和DataGridHeader_Unchecked的实现在哪里? – Xiaoy312

+0

添加相关代码 – Jmyster

回答

0

我改变了它的工作方式,并在后面添加了一个IsChecked。然后,我循环浏览数据,并对IsChecked进行扫描并刷新网格