如何将 SQL 查询绑定到数据网格

本文关键字:数据 数据网 网格 绑定 查询 SQL | 更新日期: 2024-11-06 04:08:37

    <DataGrid Name="getEmployees" ItemsSource="{Binding}">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn />
            <DataGridTextColumn />
        </DataGrid.Columns>
    </DataGrid>

这是我的数据网格

这是我的代码隐藏

    public ViewMyProxy()
    {
        InitializeComponent();            
        FillDataGrid();
    }
    private void FillDataGrid()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
        string CmdString = string.Empty;
        using (OleDbConnection con = new OleDbConnection(connectionString))
        {
            CmdString = "SELECT proxyFor, enabled FROM accesscontrol WHERE currentlyLoggedOnUser = '" + Environment.UserName + "'";
            OleDbCommand cmd = new OleDbCommand(CmdString, con);
            OleDbDataAdapter sda = new OleDbDataAdapter(cmd);
            DataTable dt = new DataTable("Employee");
            sda.Fill(dt);
            getEmployees.ItemsSource = dt.DefaultView;
        }
    }

我的问题

  1. 有没有办法加载 SQL 查询并将其直接绑定到 DataGrid?
  2. 启用的列是一个数值字段(0 = false 和 1 = true),我们可以将其绑定到 DataGridCheckBoxColumn 吗?基本上,当用户取消选中一个框时,我想尽快更新表格。

使用代码隐藏,当我的 WPF 加载时,我最终得到 3 列而不是 2 列。我希望第一列是复选框(从SQL查询启用),代理是我想要的第二列中的字符串。

如何将 SQL 查询绑定到数据网格

您需要将DataGrid.AutoGenerateColumns设置为 False ,以防止它自动生成列。然后,您需要显式绑定您自己定义的列。 DataGridCheckBoxColumnDataGridTextColumn 都具有还可以设置的其他属性,以进一步自定义网格中显示的内容。

<DataGrid 
    Name="getEmployees" 
    AutoGenerateColumns="False"
    >
    <DataGrid.Columns>
        <DataGridCheckBoxColumn 
            Binding="{Binding enabled}"
            Header="Enabled"
            />
        <DataGridTextColumn 
            Binding="{Binding proxyFor}"
            Header="Proxy For"
            />
    </DataGrid.Columns>
</DataGrid>

如果复选框列未按所需方式工作,您可以尝试编写一个值转换器以在整数和布尔值之间进行转换。

XAML(部分):

        <DataGridCheckBoxColumn 
            xmlns:myconv="clr-namespace:MyProject.Converters"
            Binding="{Binding enabled, Converter={myconv:IntToBool}}"
            />

C#

namespace MyProject.Converters
{
    public class IntToBool : MarkupExtension, IValueConverter
    {
        public override object ProvideValue(IServiceProvider serviceProvider) => this;
        public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((int)value) != 0;
        }
        public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((bool)value) ? 1 : 0;
        }
    }
}

如果这不起作用,则需要改用DataGridTemplateColumn,这将使您有更多的权力来控制列的外观和工作方式。

在回答您的第一个问题"有没有办法加载 SQL 查询并将其直接与 DataGrid 绑定?"时,我不确定这到底是什么意思:您是否在问是否可以将 SQL 字符串分配给 DataGrid 的某个属性并让它执行查询并填充自身?不。如果您确实愿意,可以编写一个附加属性来执行此操作。这可能很有趣。

还有一点,你没有问,但应该提到:

CmdString = "SELECT proxyFor, enabled FROM accesscontrol WHERE currentlyLoggedOnUser = '" 
    + Environment.UserName + "'";

如果你已经知道这是不好的做法,并且你打算在代码工作后替换它,那么你不需要听到这个,但如果不是这样,你应该真正养成使用参数的绝对习惯:

CmdString = "SELECT proxyFor, enabled FROM accesscontrol WHERE "
    + "currentlyLoggedOnUser = @userName";
OleDbCommand cmd = new OleDbCommand(CmdString, con);
cmd.Parameters.AddWithValue("userName", Environment.UserName);

如果某人的用户名中有一个引号怎么办?它可能发生。如果你在面向外部的代码中使用SQL字符串的简单串联,你就允许地球上的任何人在你的数据库中运行任意SQL。

为什么在 XAML 中具有ItemsSource="{Binding}"?这会将 DataGrid 的 DataContext 绑定到 ItemsSource。如果你的视图有一个视图模型,那么该数据上下文应该是视图模型;否则,它可能为空。无论如何,您都在代码中分配其他内容。