在 WPF 中获取 CheckBox 单元格的布尔值
Getting the boolean value of a CheckBox cell in WPF
我有一个 DataGrid
,在一行的每个第一个单元格中都有一个 Checkbox
。如果选中该单元格中的 Checkbox
,我想遍历我的 DataGrid
行并获取这些行。
这是我检查 DataGrid
:
的代码
根据 Ilan 的回答编辑:
Private Sub ApproveBtn_Clicked(sender As Object, e As RoutedEventArgs)
For i As Integer = 0 To TimeSheetAppDGrid.Items.Count - 1
TimeSheetAppDGrid.SelectedItem = TimeSheetAppDGrid.Items(i)
Dim row As Row = DirectCast(TimeSheetAppDGrid.SelectedItems(0), Row)
Dim mycheckbox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.Items(i)), ContentPresenter)
If mycheckbox Is Nothing Then
Return
End If
Dim checkBox = GetAllVisualChildren(mycheckbox).OfType(Of CheckBox)().FirstOrDefault(Function(box) box.Name = "chkSelectAll")
If checkBox Is Nothing Then
Return
End If
Dim isChecked = checkBox.Checked
If isChecked = True Then
MsgBox(row.Mark)
End If
Next
End Sub
下面的代码似乎没有被 VB.NET 接受,导致编译错误“Value of type 'FrameworkElement' cannot be converted to 'CheckBox'.
” 在网上搜索后,几乎所有的答案都包含这段代码,但是在 C# 中,所以我转换了它:
Dim mycheckbox As CheckBox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.SelectedItems(0)), CheckBox)
这个 link 是我获得代码的地方。下面是来自 C# 的原始代码行:
CheckBox mycheckbox = myGrid.Columns[5].GetCellContent(myGrid.Items[i]) as CheckBox;
这是我的 DataGrid xaml:
<DataGrid Name ="TimeSheetAppDGrid" Margin="16,200,48,0" CanUserSortColumns="False" CanUserReorderColumns="False" CanUserAddRows="False" AutoGenerateColumns="False" SelectionUnit="FullRow"
materialDesign:DataGridAssist.CellPadding="13 8 8 8" materialDesign:DataGridAssist.ColumnHeaderPadding="8" IsReadOnly="True" SelectionMode="Single" >
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource MaterialDesignDataGridRow}">
<EventSetter Event="MouseDoubleClick" Handler="Row_DoubleClick"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox Name="AllChkBox" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0"
IsChecked="{Binding IsChecked, ElementName=AllChkBox,
Mode=OneWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Path=Mark}" Header="Mark" Width="120" MaxWidth="120"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=ProjectCode}" Header="Project Code" Width="130" MaxWidth="130"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Project}" Header="Project" Width="250" MaxWidth="250"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=PM}" Header="Project Manager" Width="230" MaxWidth="230"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Activity}" Header="Activity" Width="600" MaxWidth="600"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Today}" Header="Date" Width="200" MaxWidth="200"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Regular}" Header="Regular" Width="130" MaxWidth="130"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Overtime}" Header="Overtime" Width="130" MaxWidth="130"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</DataGridTextColumn.ElementStyle>
</materialDesign:MaterialDataGridTextColumn>
</DataGrid.Columns>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MaterialDesignDataGridCell}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
</DataGrid.CellStyle>
</DataGrid>
有什么建议吗?
我认为您采用的解决方案存在一些概念错误:
CheckBox mycheckbox = myGrid.Columns[5].GetCellContent(myGrid.Items[i]) as CheckBox;
我已经检查过了,当我们使用 DataGridTemplateColumn.CellTemplate
时,就像您的情况一样,接受的值 (mycheckbox) 是 ContentPresenter,因为单元格后面有 DataTemplate(因为您正在使用数据模板)。这就是代码实际上不起作用的原因。
我建议您的解决方案是从 ContentPresenter 获取复选框对象(代码在 C# 中,您必须将其转换为 VB),因为它是 ContentPresenter 的视觉子对象(您可以在 Snoop 中找到它)。
更新这里是GetAllVisualChildren代码:
public static class VisualTreeHelperExtensions
{
public static T FindParent<T>(this DependencyObject child) where T : DependencyObject
{
while (true)
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
child = parentObject;
}
}
public static List<DependencyObject> GetAllVisualChildren(this DependencyObject parent)
{
var resultedList = new List<DependencyObject>();
var visualQueue = new Queue<DependencyObject>();
visualQueue.Enqueue(parent);
do
{
var depObj = visualQueue.Dequeue();
var childrenCount = VisualTreeHelper.GetChildrenCount(depObj);
for (int i = 0; i < childrenCount; i++)
{
var v = VisualTreeHelper.GetChild(depObj, i);
visualQueue.Enqueue(v);
}
resultedList.Add(depObj);
} while (visualQueue.Count > 0);
resultedList.RemoveAt(0);
return resultedList;
}
}
做接下来的事情以将 VisualTreeHelperExtensions class 导入到 VB
- 创建 C# class 库作为解决方案的一部分。
- 将 VisualTreeHelperExtensions class 添加到新创建的项目中。
- 编译您的 C# class 库。
- 将新创建(和编译)的 class 库作为参考 (dll) 添加到您的 vb.net 项目中。
更新 #3 - 更改了 vb 代码
Dim mycheckbox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.Items(0)), ContentPresenter)
If mycheckbox Is Nothing Then
Return
End If
Dim checkBox = mycheckbox.GetAllVisualChildren().OfType(Of CheckBox)().FirstOrDefault(Function(box) box.Name = "chkSelectAll")
If checkBox Is Nothing Then
Return
End If
Dim isChecked = checkBox.IsChecked
If isChecked = True Then
MsgBox("Checked")
End If
VB.net 复选框示例
因为 .net CheckBox 有它的 IsChecked 布尔状态表示器。
此致。
编辑
好的,这里有一种更精确的方法来实现您的需要,而无需搜索可视化树以查找复选框(同样在 c# 中,但希望翻译起来不难)。
首先,我创建了一个 Student class 来绑定到实现 INotifyPropertyChanged :
public class Student:INotifyPropertyChanged
{
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set { _isChecked = value;
OnPropertyChanged("IsChecked");
}
}
public string Mark { get; set; }
public string ProjectCode { get; set; }
public string Project { get; set; }
public string PM { get; set; }
public string Activity { get; set; }
public DateTime Today { get; set; }
public string Regular { get; set; }
public string Overtime { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后我用测试数据在我的数据网格中添加一行:
TimeSheetAppDGrid.ItemsSource = new List<Student>()
{
new Student { ProjectCode="Project1",Mark = "A",Today = DateTime.Today}
};
在数据模板的 XAML 中,我已将绑定更改为 而不是 绑定到 header 复选框,但绑定到学生 IsChecked 属性 并且我在 header 单元格中为 AllChkBox 复选框添加了一个点击处理程序:
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox Click="AllChkBox_OnClick" Name="AllChkBox" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0"
IsChecked="{Binding Path=IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
对于 AllChkBox 单击处理程序 (AllChkBox_OnClick),我遍历每个数据源(即学生)并将 IsChecked 属性 切换为 AllChkBox 检查值:
private void AllChkBox_OnClick(object sender, RoutedEventArgs e)
{
foreach (var s in TimeSheetAppDGrid.ItemsSource)
{
Student st = s as Student;
st.IsChecked = (bool) AllChkBox.IsChecked;
}
}
现在可以询问每个项目源(即学生)的 IsChecked 属性(绑定到相应的复选框单元格),而无需四处寻找复选框(请原谅双关语)即
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
foreach (var source in TimeSheetAppDGrid.ItemsSource)
{
Student st = source as Student;
if (st.IsChecked)
MessageBox.Show("Is Checked");
}
}
您必须查看使用 Snoop
生成的可视化树,以便您的转换正常工作。
最简单的方法是根据 CheckBox
的 Checked/Unchecked
事件不断更新 Dictionary<int, DataGridRow>
。
抱歉,代码是用 C# 编写的。
XAML :
<CheckBox Name="AllChkBox" Checked="AllChkBox_Checked" Unchecked="AllChkBox_Unchecked" />
<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0"
Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked"
IsChecked="{Binding IsChecked, ElementName=AllChkBox, Mode=OneWay}"/>
代码:
Dictionary<int, DataGridRow> rows = new Dictionary<int, DataGridRow>();
private void chkSelectAll_Checked(object sender, RoutedEventArgs e)
{
var cur_item = DGrid.CurrentItem;
int cur_index = DGrid.Items.IndexOf(cur_item);
if (cur_index == -1) // header checkbox is checked
return;
DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(cur_item);
rows.Add(DGrid.Items.IndexOf(cur_item), row);
}
private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e)
{
var cur_item = DGrid.CurrentItem;
rows.Remove(DGrid.Items.IndexOf(cur_item));
}
private void AllChkBox_Checked(object sender, RoutedEventArgs e)
{
foreach (var item in DGrid.Items)
{
DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(item);
rows.Add(DGrid.Items.IndexOf(item), row);
}
}
private void AllChkBox_Unchecked(object sender, RoutedEventArgs e)
{
rows.Clear();
}
我有一个 DataGrid
,在一行的每个第一个单元格中都有一个 Checkbox
。如果选中该单元格中的 Checkbox
,我想遍历我的 DataGrid
行并获取这些行。
这是我检查 DataGrid
:
根据 Ilan 的回答编辑:
Private Sub ApproveBtn_Clicked(sender As Object, e As RoutedEventArgs)
For i As Integer = 0 To TimeSheetAppDGrid.Items.Count - 1
TimeSheetAppDGrid.SelectedItem = TimeSheetAppDGrid.Items(i)
Dim row As Row = DirectCast(TimeSheetAppDGrid.SelectedItems(0), Row)
Dim mycheckbox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.Items(i)), ContentPresenter)
If mycheckbox Is Nothing Then
Return
End If
Dim checkBox = GetAllVisualChildren(mycheckbox).OfType(Of CheckBox)().FirstOrDefault(Function(box) box.Name = "chkSelectAll")
If checkBox Is Nothing Then
Return
End If
Dim isChecked = checkBox.Checked
If isChecked = True Then
MsgBox(row.Mark)
End If
Next
End Sub
下面的代码似乎没有被 VB.NET 接受,导致编译错误“Value of type 'FrameworkElement' cannot be converted to 'CheckBox'.
” 在网上搜索后,几乎所有的答案都包含这段代码,但是在 C# 中,所以我转换了它:
Dim mycheckbox As CheckBox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.SelectedItems(0)), CheckBox)
这个 link 是我获得代码的地方。下面是来自 C# 的原始代码行:
CheckBox mycheckbox = myGrid.Columns[5].GetCellContent(myGrid.Items[i]) as CheckBox;
这是我的 DataGrid xaml:
<DataGrid Name ="TimeSheetAppDGrid" Margin="16,200,48,0" CanUserSortColumns="False" CanUserReorderColumns="False" CanUserAddRows="False" AutoGenerateColumns="False" SelectionUnit="FullRow"
materialDesign:DataGridAssist.CellPadding="13 8 8 8" materialDesign:DataGridAssist.ColumnHeaderPadding="8" IsReadOnly="True" SelectionMode="Single" >
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource MaterialDesignDataGridRow}">
<EventSetter Event="MouseDoubleClick" Handler="Row_DoubleClick"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox Name="AllChkBox" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0"
IsChecked="{Binding IsChecked, ElementName=AllChkBox,
Mode=OneWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Path=Mark}" Header="Mark" Width="120" MaxWidth="120"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=ProjectCode}" Header="Project Code" Width="130" MaxWidth="130"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Project}" Header="Project" Width="250" MaxWidth="250"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=PM}" Header="Project Manager" Width="230" MaxWidth="230"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Activity}" Header="Activity" Width="600" MaxWidth="600"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Today}" Header="Date" Width="200" MaxWidth="200"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Regular}" Header="Regular" Width="130" MaxWidth="130"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}"/>
<materialDesign:MaterialDataGridTextColumn Binding="{Binding Path=Overtime}" Header="Overtime" Width="130" MaxWidth="130"
EditingElementStyle="{StaticResource MaterialDesignDataGridTextColumnPopupEditingStyle}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource MaterialDesignDataGridColumnHeader}">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</DataGridTextColumn.ElementStyle>
</materialDesign:MaterialDataGridTextColumn>
</DataGrid.Columns>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MaterialDesignDataGridCell}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
</DataGrid.CellStyle>
</DataGrid>
有什么建议吗?
我认为您采用的解决方案存在一些概念错误:
CheckBox mycheckbox = myGrid.Columns[5].GetCellContent(myGrid.Items[i]) as CheckBox;
我已经检查过了,当我们使用 DataGridTemplateColumn.CellTemplate
时,就像您的情况一样,接受的值 (mycheckbox) 是 ContentPresenter,因为单元格后面有 DataTemplate(因为您正在使用数据模板)。这就是代码实际上不起作用的原因。
我建议您的解决方案是从 ContentPresenter 获取复选框对象(代码在 C# 中,您必须将其转换为 VB),因为它是 ContentPresenter 的视觉子对象(您可以在 Snoop 中找到它)。
更新这里是GetAllVisualChildren代码:
public static class VisualTreeHelperExtensions
{
public static T FindParent<T>(this DependencyObject child) where T : DependencyObject
{
while (true)
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
child = parentObject;
}
}
public static List<DependencyObject> GetAllVisualChildren(this DependencyObject parent)
{
var resultedList = new List<DependencyObject>();
var visualQueue = new Queue<DependencyObject>();
visualQueue.Enqueue(parent);
do
{
var depObj = visualQueue.Dequeue();
var childrenCount = VisualTreeHelper.GetChildrenCount(depObj);
for (int i = 0; i < childrenCount; i++)
{
var v = VisualTreeHelper.GetChild(depObj, i);
visualQueue.Enqueue(v);
}
resultedList.Add(depObj);
} while (visualQueue.Count > 0);
resultedList.RemoveAt(0);
return resultedList;
}
}
做接下来的事情以将 VisualTreeHelperExtensions class 导入到 VB
- 创建 C# class 库作为解决方案的一部分。
- 将 VisualTreeHelperExtensions class 添加到新创建的项目中。
- 编译您的 C# class 库。
- 将新创建(和编译)的 class 库作为参考 (dll) 添加到您的 vb.net 项目中。
更新 #3 - 更改了 vb 代码
Dim mycheckbox = TryCast(TimeSheetAppDGrid.Columns(0).GetCellContent(TimeSheetAppDGrid.Items(0)), ContentPresenter)
If mycheckbox Is Nothing Then
Return
End If
Dim checkBox = mycheckbox.GetAllVisualChildren().OfType(Of CheckBox)().FirstOrDefault(Function(box) box.Name = "chkSelectAll")
If checkBox Is Nothing Then
Return
End If
Dim isChecked = checkBox.IsChecked
If isChecked = True Then
MsgBox("Checked")
End If
VB.net 复选框示例
因为 .net CheckBox 有它的 IsChecked 布尔状态表示器。
此致。
编辑
好的,这里有一种更精确的方法来实现您的需要,而无需搜索可视化树以查找复选框(同样在 c# 中,但希望翻译起来不难)。 首先,我创建了一个 Student class 来绑定到实现 INotifyPropertyChanged :
public class Student:INotifyPropertyChanged
{
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set { _isChecked = value;
OnPropertyChanged("IsChecked");
}
}
public string Mark { get; set; }
public string ProjectCode { get; set; }
public string Project { get; set; }
public string PM { get; set; }
public string Activity { get; set; }
public DateTime Today { get; set; }
public string Regular { get; set; }
public string Overtime { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后我用测试数据在我的数据网格中添加一行:
TimeSheetAppDGrid.ItemsSource = new List<Student>()
{
new Student { ProjectCode="Project1",Mark = "A",Today = DateTime.Today}
};
在数据模板的 XAML 中,我已将绑定更改为 而不是 绑定到 header 复选框,但绑定到学生 IsChecked 属性 并且我在 header 单元格中为 AllChkBox 复选框添加了一个点击处理程序:
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<CheckBox Click="AllChkBox_OnClick" Name="AllChkBox" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0"
IsChecked="{Binding Path=IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
对于 AllChkBox 单击处理程序 (AllChkBox_OnClick),我遍历每个数据源(即学生)并将 IsChecked 属性 切换为 AllChkBox 检查值:
private void AllChkBox_OnClick(object sender, RoutedEventArgs e)
{
foreach (var s in TimeSheetAppDGrid.ItemsSource)
{
Student st = s as Student;
st.IsChecked = (bool) AllChkBox.IsChecked;
}
}
现在可以询问每个项目源(即学生)的 IsChecked 属性(绑定到相应的复选框单元格),而无需四处寻找复选框(请原谅双关语)即
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
foreach (var source in TimeSheetAppDGrid.ItemsSource)
{
Student st = source as Student;
if (st.IsChecked)
MessageBox.Show("Is Checked");
}
}
您必须查看使用 Snoop
生成的可视化树,以便您的转换正常工作。
最简单的方法是根据 CheckBox
的 Checked/Unchecked
事件不断更新 Dictionary<int, DataGridRow>
。
抱歉,代码是用 C# 编写的。
XAML :
<CheckBox Name="AllChkBox" Checked="AllChkBox_Checked" Unchecked="AllChkBox_Unchecked" />
<CheckBox Name="chkSelectAll" Margin="3.5 0 0 0"
Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked"
IsChecked="{Binding IsChecked, ElementName=AllChkBox, Mode=OneWay}"/>
代码:
Dictionary<int, DataGridRow> rows = new Dictionary<int, DataGridRow>();
private void chkSelectAll_Checked(object sender, RoutedEventArgs e)
{
var cur_item = DGrid.CurrentItem;
int cur_index = DGrid.Items.IndexOf(cur_item);
if (cur_index == -1) // header checkbox is checked
return;
DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(cur_item);
rows.Add(DGrid.Items.IndexOf(cur_item), row);
}
private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e)
{
var cur_item = DGrid.CurrentItem;
rows.Remove(DGrid.Items.IndexOf(cur_item));
}
private void AllChkBox_Checked(object sender, RoutedEventArgs e)
{
foreach (var item in DGrid.Items)
{
DataGridRow row = (DataGridRow)DGrid.ItemContainerGenerator.ContainerFromItem(item);
rows.Add(DGrid.Items.IndexOf(item), row);
}
}
private void AllChkBox_Unchecked(object sender, RoutedEventArgs e)
{
rows.Clear();
}