如何将SQL查询绑定到DataGrid?

时间:2016-04-22 12:19:18

标签: c# wpf datagrid

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

这是我的DataGrid

这是我的CodeBehind

    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吗?基本上,当用户取消选中一个框时,我想尽快更新表格。
  3. 使用代码隐藏,当我的WPF加载时,我最终得到3列而不是2.我希望第1列是Checkbox(从SQL查询启用),而proxyFor是我想要的字符串第二栏。

1 个答案:

答案 0 :(得分:2)

您需要将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>

如果复选框列不能按您希望的方式工作,您可以尝试编写value converter以在整数和布尔值之间进行转换。

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);

如果somebody has a single quote in his user name怎么办?这有可能发生。如果在外部代码中使用简单的SQL字符串连接,则允许地球上的任何人在数据库中运行任意SQL。

为什么XAML中有ItemsSource="{Binding}"?这将把DataGrid的DataContext绑定到ItemsSource。如果您的视图具有viewmodel,那么DataContext应该是viewmodel;否则,它可能是空的。无论如何,你在代码中分配其他东西。