C# DataGridTemplateColumn中的复选框有问题

C# DataGridTemplateColumn中的复选框有问题,c#,wpf,datagrid,C#,Wpf,Datagrid,我需要帮助来完成我的第一个小应用程序。我正在尝试对datagrid中的checked行执行操作 xaml: <DataGrid x:Name="dgConnected_Users" AutoGenerateColumns="False" IsReadOnly="True" Height="180" Background="Azure" ScrollViewer

我需要帮助来完成我的第一个小应用程序。我正在尝试对datagrid中的checked行执行操作

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>

Déconnecter le(s)Usilizateur(s)
Fabrice BERTRAND
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
        }
    }
private void UID\u Disconnect\u单击(对象发送器,路由目标)
{
///bouton’UID_Disconnect’区域利用者连接示意图
/// 
IEnumerable UsersInDatabase=dgConnected_Users.Items.OfType()。其中(usr=>usr.IsChecked==true);
foreach(UsersInDatabase中的复选框usr)
{
MessageBox.Show(“耶”);///在这里做事
}
}
我现在正在用MessageBox测试代码。但什么也没发生。帮我完成项目的想法

事实上,我需要为选中复选框的每一行获取UID_用户名以执行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);
        }
    }
private void refresh\u单击(对象发送方,路由目标)
{
尝试
{
if(Cnx.State==System.Data.ConnectionState.Open)
{
Cnx.Close();
}
if(cmbauthentication.Text.Equals(“Windows”))
{
SQL_Connection.ConnectionString=@“Server=“+txtServerName.Text+”;集成安全性=SSPI;”;
Cnx.ConnectionString=SQL\u Connection.ConnectionString;
}
else if(cmbauthentication.Text.Equals(“SQL Server”))
{
SQL_Connection.ConnectionString=@“Server=“+txtServerName.Text+”;User ID=“+txtserid.Text+”;Password=“+txtserverpwd.Password+”;
Cnx.ConnectionString=SQL\u Connection.ConnectionString;
}
Cnx.Open();
Cmd.Connection=Cnx;
Cmd.CommandText=(“使用\”“+cmbDatabase.Text+”\“从cbUserSession a内部联接主机中选择不同的b.nt\\用户名作为[UID\\用户名],b.hostname作为[UID\\计算机名]。在a.cbUserName=b.spid上处理b,其中a.cbUserName不为NULL;”;
SqlDataAdapter da=新的SqlDataAdapter(Cmd);
dt=新数据表(“已连接用户”);
da.填充(dt);

///Add(newdatacolumn(“IsChecked”,typeof(bool));为了向您展示工作副本,我构建了代码的其余部分

我假设您有一个类对象,您将其绑定为数据网格的项源。 仅供参考,我已经创建了自己的类对象。请参见下文,并根据您的类文件进行更改

步骤1-类创建

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);
        }
    }
private void UID\u Disconnect\u OnClick(对象发送方,RoutedEventArgs e)
{
var selectedItems=dgConnected_Users.Items.Cast(),其中(x=>x.IsChecked);
foreach(selectedItems中的变量项)
{
MessageBox.Show(item.UID\u ComputerName+“”+item.UID\u用户名);
}
}
在上面的代码中,我使用了“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);
    }
}
private void refresh\u单击(对象发送方,路由目标)
{
尝试
{
if(Cnx.State==System.Data.ConnectionState.Open)
{
Cnx.Close();
}
if(cmbauthentication.Text.Equals(“Windows”))
{
SQL_Connection.ConnectionString=@“Server=“+txtServerName.Text+”;集成安全性=SSPI;”;
Cnx.ConnectionString=SQL\u Connection.ConnectionString;
}
else if(cmbauthentication.Text.Equals(“SQL Server”))
{
SQL_Connection.ConnectionString=@“Server=“+txtServerName.Text+”;User ID=“+txtserid.Text+”;Password=“+txtserverpwd.Password+”;
Cnx.ConnectionString=SQL\u Connection.ConnectionString;
}
Cnx.Open();
Cmd.Connection=Cnx;
Cmd.CommandText=(“使用\”“+cmbDatabase.Text+”\“从cbUserSession a内部联接主机中选择不同的b.nt\\用户名作为[UID\\用户名],b.hostname作为[UID\\计算机名]。在a.cbUserName=b.spid上处理b,其中a.cbUserName不为NULL;”;
//SqlDataAdapter da=新的SqlDataAdapter(Cmd);
//dt=新数据表(“已连接用户”);
//da.填充(dt);

//dt.Columns.Add(newdatacolumn(“IsChecked”,typeof(bool)));感谢我们的回答。我已经尝试了我们的代码,但出现了一些问题。像其他尝试一样,我们的