我有DataGrid
在行的每个第一个单元格中都有Checkbox
。我想循环遍历DataGrid
行并在检查该单元格中的Checkbox
时获取行。
这是检查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>
有什么建议吗?
答案 0 :(得分:1)
您必须查看使用Snoop
生成的可视树,以便您的演员阵容正常运行。
最简单的方法是在Dictionary<int, DataGridRow>
的{{1}}事件后不断更新Checked/Unchecked
。
对不起,代码在C#中。
XAML:
CheckBox
代码:
<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}"/>
答案 1 :(得分:0)
在我看来,您采用的解决方案存在一些概念错误:
CheckBox mycheckbox = myGrid.Columns [5] .GetCellContent(myGrid.Items [i])为CheckBox;
我已经检查了它,当我们使用DataGridTemplateColumn.CellTemplate
时,就像你的情况一样,接受的值(mycheckbox)是ContentPresenter,因为在单元格后面有DataTemplate(因为你正在使用DataTemplate) )。这就是代码实际上无法正常工作的原因。
我建议你的解决方案是从ContentPresenter获取复选框对象(代码在C#中你必须将其转换为VB),因为它是ContentPresenter的可视子代(你可以在Snoop)。
UpdateHere是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类导入VB
更新#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 CheckBox示例
因为所有.net CheckBox都有其IsChecked布尔状态演示者。
问候。
答案 2 :(得分:0)
修改
好的,这里有一个更精致的方法来实现你所需要的,而不必搜索可视树寻找复选框(再次在c#中,但希望不应该难以翻译)。 首先,我创建了一个绑定到其上的Student类来实现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中,我已将绑定更改为而不是绑定到标题复选框,但绑定到学生IsChecked属性,并且我添加了一个单击的处理程序对于标题单元格中的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),我遍历每个数据源(即Student)并将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");
}
}