DataGridTemplateColumn 中的复选框有问题
Problem with checkbox in DataGridTemplateColumn
我需要帮助来完成我的第一个小应用程序。我正在尝试对数据网格中选中的行执行操作。
xaml :
<DataGrid x:Name="dgConnected_Users" AutoGenerateColumns="False" IsReadOnly="True" Height="180" Background="Azure" ScrollViewer.CanContentScroll="True" FontSize="11" BorderBrush="#26BFF0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" BorderThickness="2,2,2,2" HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" RowHeight="20" RowBackground="Azure" GridLinesVisibility="Horizontal" HorizontalGridLinesBrush="DarkOrange" Margin="10,0,10,0">
<DataGrid.Columns>
<DataGridTextColumn x:Name="UID_UserName" FontFamily="Segoe UI Bold" Binding="{Binding UID_UserName}" Header="Utilisateur" Width="1*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="5,0"></Setter>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn x:Name="UID_ComputerName" Binding="{Binding UID_ComputerName}" Header="Machine" Width="1*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="5,0"></Setter>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTemplateColumn x:Name="UID_Chkbox" Width="24">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock TextAlignment="Center" VerticalAlignment="Center"><CheckBox x:Name="Chk_UID_IsSelected" IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Checked="Chk_UID_IsSelected_Checked" Unchecked="Chk_UID_IsSelected_Unchecked" Click="Chk_UID_IsSelected_Click"/></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.Header>
<Image Source="components/resources/images/delete-24.png" Height="12" Width="12" StretchDirection="Both" Stretch="Fill"/>
</DataGridTemplateColumn.Header>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<StackPanel Margin="10,10">
<Button x:Name="UID_Disconnect" Width="270" Click="UID_Disconnect_Click">Déconnecter le(s) utilisateur(s)</Button>
</StackPanel>
<StackPanel Margin="10,0">
<Grid>
<Border BorderBrush="#26BFF0" BorderThickness="0,1,0,0">
<TextBlock HorizontalAlignment="Center" FontFamily="Segoe UI Light" FontSize="10" Padding="5" Foreground="#FF4C4F54">InovaGes SAS · Développé par Fabrice BERTRAND</TextBlock>
</Border>
</Grid>
</StackPanel>
xaml.cs :
private void UID_Disconnect_Click(object sender, RoutedEventArgs e)
{
/// gestion de la déconnexion des utilisateurs au clic du bouton 'UID_Disconnect'
///
IEnumerable<CheckBox> UsersInDatabase = dgConnected_Users.Items.OfType<CheckBox>().Where(usr => usr.IsChecked == true);
foreach (CheckBox usr in UsersInDatabase)
{
MessageBox.Show("yeah"); /// do stuff here
}
}
我现在正在使用 MessageBox 测试代码。但什么也没有发生。帮助我完成项目的想法?
事实上,我需要为选中复选框的每一行获取 UID_UserName 执行 sql 删除。
我也尝试过使用 DataRowView。我可以获得 TextColumn,但没有复选框。
编辑 1 :
我认为部分问题是由于带有复选框的列不在 dt 中:
private void refresh_Click(object sender, RoutedEventArgs e)
{
try
{
if (Cnx.State == System.Data.ConnectionState.Open)
{
Cnx.Close();
}
if (cmbAuthentification.Text.Equals("Windows"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; Integrated Security = SSPI;";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
else if (cmbAuthentification.Text.Equals("SQL Server"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; User ID =" + txtUserID.Text + "; Password=" + txtUserPwd.Password + ";";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
Cnx.Open();
Cmd.Connection = Cnx;
Cmd.CommandText = ("USE \"" + cmbDatabase.Text + "\";SELECT DISTINCT b.nt_username AS [UID_UserName], b.hostname AS [UID_ComputerName] FROM cbUserSession a INNER JOIN master..sysprocesses b ON a.cbSession = b.spid WHERE a.cbUserName IS NOT NULL;");
SqlDataAdapter da = new SqlDataAdapter(Cmd);
dt = new DataTable("Connected_Users");
da.Fill(dt);
/// dt.Columns.Add(new DataColumn("IsChecked", typeof(bool))); <-- maybe need to do something like that ?
dgConnected_Users.ItemsSource = dt.DefaultView;
Cnx.Close();
}
catch (Exception exception)
{
MessageBox.Show("Erreur de chargement des données pour le motif suivant : \n" + exception.Message, "OOoopssss !!!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
为了向您展示工作副本,我构建了其余代码。
我假设您有一个 class 对象,您将其作为项目源绑定到数据网格。
仅供参考,我创建了自己的 class 对象。请参阅下文并根据您的 class 文件进行更改。
步骤 1 - Class 创建
public class DataGridUser
{
public string UID_UserName { get; set; }
public string UID_ComputerName { get; set; }
public bool IsChecked { get; set; }
}
第 2 步 - 单击按钮时,我只是修改了如下代码。
private void UID_Disconnect_OnClick(object sender, RoutedEventArgs e)
{
var selectedItems = dgConnected_Users.Items.Cast<DataGridUser>().Where(x => x.IsChecked);
foreach (var item in selectedItems)
{
MessageBox.Show(item.UID_ComputerName + " " + item.UID_UserName);
}
}
在上面的代码中,我使用了“Cast”类型并将项目转换为数据网格绑定到的类型 DataGridUser(在本例中)。
其余代码与您的相同。
编辑
添加了代码来回答您的评论。
第 3 步 我复制了您的事件处理程序,然后稍作修改。请仔细比较代码和阅读注释,然后在您的程序中使用它。
private void refresh_Click(object sender, RoutedEventArgs e)
{
try
{
if (Cnx.State == System.Data.ConnectionState.Open)
{
Cnx.Close();
}
if (cmbAuthentification.Text.Equals("Windows"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; Integrated Security = SSPI;";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
else if (cmbAuthentification.Text.Equals("SQL Server"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; User ID =" + txtUserID.Text + "; Password=" + txtUserPwd.Password + ";";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
Cnx.Open();
Cmd.Connection = Cnx;
Cmd.CommandText = ("USE \"" + cmbDatabase.Text + "\";SELECT DISTINCT b.nt_username AS [UID_UserName], b.hostname AS [UID_ComputerName] FROM cbUserSession a INNER JOIN master..sysprocesses b ON a.cbSession = b.spid WHERE a.cbUserName IS NOT NULL;");
//SqlDataAdapter da = new SqlDataAdapter(Cmd);
//dt = new DataTable("Connected_Users");
//da.Fill(dt);
// dt.Columns.Add(new DataColumn("IsChecked", typeof(bool))); <-- maybe need to do something like that ?
// GK - Instead of using SqlDataAdapter. Use DataReader and transfer the data from DataReader to an object. See below.
SqlDataReader reader = Cmd.ExecuteReader();
var dataGridUserCollection = new List<DataGridUser>();
if (reader.HasRows)
{
while (reader.Read())
{
var currentDataGridUser = new DataGridUser()
{
UID_UserName = reader["UID_UserName"].ToString(),
UID_ComputerName = reader["UID_ComputerName"].ToString()
};
dataGridUserCollection.Add(currentDataGridUser);
}
}
// GK - Bind new list object to DataGrid.
// GK - Now the object bound to DataGrid is of type DataGridUser.
// GK - So now when you do the type casting to DataGridUser on your button click
// it won't throw any more error.
//dgConnected_Users.ItemsSource = dt.DefaultView;
dgConnected_Users.ItemsSource = dataGridUserCollection;
Cnx.Close();
}
catch (Exception exception)
{
MessageBox.Show("Erreur de chargement des données pour le motif suivant : \n" + exception.Message, "OOoopssss !!!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
注意:-我假设列是字符串类型,然后将它们转换为字符串。在您 运行 您的代码之前,您应该处理这些最少的事情。
如果您仍然遇到任何问题,请告诉我们。
我需要帮助来完成我的第一个小应用程序。我正在尝试对数据网格中选中的行执行操作。
xaml :
<DataGrid x:Name="dgConnected_Users" AutoGenerateColumns="False" IsReadOnly="True" Height="180" Background="Azure" ScrollViewer.CanContentScroll="True" FontSize="11" BorderBrush="#26BFF0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" BorderThickness="2,2,2,2" HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" RowHeight="20" RowBackground="Azure" GridLinesVisibility="Horizontal" HorizontalGridLinesBrush="DarkOrange" Margin="10,0,10,0">
<DataGrid.Columns>
<DataGridTextColumn x:Name="UID_UserName" FontFamily="Segoe UI Bold" Binding="{Binding UID_UserName}" Header="Utilisateur" Width="1*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="5,0"></Setter>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn x:Name="UID_ComputerName" Binding="{Binding UID_ComputerName}" Header="Machine" Width="1*">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="5,0"></Setter>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTemplateColumn x:Name="UID_Chkbox" Width="24">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock TextAlignment="Center" VerticalAlignment="Center"><CheckBox x:Name="Chk_UID_IsSelected" IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Checked="Chk_UID_IsSelected_Checked" Unchecked="Chk_UID_IsSelected_Unchecked" Click="Chk_UID_IsSelected_Click"/></TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.Header>
<Image Source="components/resources/images/delete-24.png" Height="12" Width="12" StretchDirection="Both" Stretch="Fill"/>
</DataGridTemplateColumn.Header>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<StackPanel Margin="10,10">
<Button x:Name="UID_Disconnect" Width="270" Click="UID_Disconnect_Click">Déconnecter le(s) utilisateur(s)</Button>
</StackPanel>
<StackPanel Margin="10,0">
<Grid>
<Border BorderBrush="#26BFF0" BorderThickness="0,1,0,0">
<TextBlock HorizontalAlignment="Center" FontFamily="Segoe UI Light" FontSize="10" Padding="5" Foreground="#FF4C4F54">InovaGes SAS · Développé par Fabrice BERTRAND</TextBlock>
</Border>
</Grid>
</StackPanel>
xaml.cs :
private void UID_Disconnect_Click(object sender, RoutedEventArgs e)
{
/// gestion de la déconnexion des utilisateurs au clic du bouton 'UID_Disconnect'
///
IEnumerable<CheckBox> UsersInDatabase = dgConnected_Users.Items.OfType<CheckBox>().Where(usr => usr.IsChecked == true);
foreach (CheckBox usr in UsersInDatabase)
{
MessageBox.Show("yeah"); /// do stuff here
}
}
我现在正在使用 MessageBox 测试代码。但什么也没有发生。帮助我完成项目的想法?
事实上,我需要为选中复选框的每一行获取 UID_UserName 执行 sql 删除。
我也尝试过使用 DataRowView。我可以获得 TextColumn,但没有复选框。
编辑 1 :
我认为部分问题是由于带有复选框的列不在 dt 中:
private void refresh_Click(object sender, RoutedEventArgs e)
{
try
{
if (Cnx.State == System.Data.ConnectionState.Open)
{
Cnx.Close();
}
if (cmbAuthentification.Text.Equals("Windows"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; Integrated Security = SSPI;";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
else if (cmbAuthentification.Text.Equals("SQL Server"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; User ID =" + txtUserID.Text + "; Password=" + txtUserPwd.Password + ";";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
Cnx.Open();
Cmd.Connection = Cnx;
Cmd.CommandText = ("USE \"" + cmbDatabase.Text + "\";SELECT DISTINCT b.nt_username AS [UID_UserName], b.hostname AS [UID_ComputerName] FROM cbUserSession a INNER JOIN master..sysprocesses b ON a.cbSession = b.spid WHERE a.cbUserName IS NOT NULL;");
SqlDataAdapter da = new SqlDataAdapter(Cmd);
dt = new DataTable("Connected_Users");
da.Fill(dt);
/// dt.Columns.Add(new DataColumn("IsChecked", typeof(bool))); <-- maybe need to do something like that ?
dgConnected_Users.ItemsSource = dt.DefaultView;
Cnx.Close();
}
catch (Exception exception)
{
MessageBox.Show("Erreur de chargement des données pour le motif suivant : \n" + exception.Message, "OOoopssss !!!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
为了向您展示工作副本,我构建了其余代码。
我假设您有一个 class 对象,您将其作为项目源绑定到数据网格。 仅供参考,我创建了自己的 class 对象。请参阅下文并根据您的 class 文件进行更改。
步骤 1 - Class 创建
public class DataGridUser
{
public string UID_UserName { get; set; }
public string UID_ComputerName { get; set; }
public bool IsChecked { get; set; }
}
第 2 步 - 单击按钮时,我只是修改了如下代码。
private void UID_Disconnect_OnClick(object sender, RoutedEventArgs e)
{
var selectedItems = dgConnected_Users.Items.Cast<DataGridUser>().Where(x => x.IsChecked);
foreach (var item in selectedItems)
{
MessageBox.Show(item.UID_ComputerName + " " + item.UID_UserName);
}
}
在上面的代码中,我使用了“Cast”类型并将项目转换为数据网格绑定到的类型 DataGridUser(在本例中)。
其余代码与您的相同。
编辑 添加了代码来回答您的评论。
第 3 步 我复制了您的事件处理程序,然后稍作修改。请仔细比较代码和阅读注释,然后在您的程序中使用它。
private void refresh_Click(object sender, RoutedEventArgs e)
{
try
{
if (Cnx.State == System.Data.ConnectionState.Open)
{
Cnx.Close();
}
if (cmbAuthentification.Text.Equals("Windows"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; Integrated Security = SSPI;";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
else if (cmbAuthentification.Text.Equals("SQL Server"))
{
SQL_Connection.ConnectionString = @"Server = " + txtServerName.Text + "; User ID =" + txtUserID.Text + "; Password=" + txtUserPwd.Password + ";";
Cnx.ConnectionString = SQL_Connection.ConnectionString;
}
Cnx.Open();
Cmd.Connection = Cnx;
Cmd.CommandText = ("USE \"" + cmbDatabase.Text + "\";SELECT DISTINCT b.nt_username AS [UID_UserName], b.hostname AS [UID_ComputerName] FROM cbUserSession a INNER JOIN master..sysprocesses b ON a.cbSession = b.spid WHERE a.cbUserName IS NOT NULL;");
//SqlDataAdapter da = new SqlDataAdapter(Cmd);
//dt = new DataTable("Connected_Users");
//da.Fill(dt);
// dt.Columns.Add(new DataColumn("IsChecked", typeof(bool))); <-- maybe need to do something like that ?
// GK - Instead of using SqlDataAdapter. Use DataReader and transfer the data from DataReader to an object. See below.
SqlDataReader reader = Cmd.ExecuteReader();
var dataGridUserCollection = new List<DataGridUser>();
if (reader.HasRows)
{
while (reader.Read())
{
var currentDataGridUser = new DataGridUser()
{
UID_UserName = reader["UID_UserName"].ToString(),
UID_ComputerName = reader["UID_ComputerName"].ToString()
};
dataGridUserCollection.Add(currentDataGridUser);
}
}
// GK - Bind new list object to DataGrid.
// GK - Now the object bound to DataGrid is of type DataGridUser.
// GK - So now when you do the type casting to DataGridUser on your button click
// it won't throw any more error.
//dgConnected_Users.ItemsSource = dt.DefaultView;
dgConnected_Users.ItemsSource = dataGridUserCollection;
Cnx.Close();
}
catch (Exception exception)
{
MessageBox.Show("Erreur de chargement des données pour le motif suivant : \n" + exception.Message, "OOoopssss !!!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
注意:-我假设列是字符串类型,然后将它们转换为字符串。在您 运行 您的代码之前,您应该处理这些最少的事情。
如果您仍然遇到任何问题,请告诉我们。