WPF 将 DataTable 列绑定到文本框

发布于 2024-12-02 04:10:54 字数 2010 浏览 0 评论 0原文

我开始使用 WPF,发现即使是最简单的绑定也很难工作。这里有一些给定...

我有一个对象,它查询现有数据库并返回一个“datatable”对象,数据返回(出于测试目的,只有一行和一列,称为“MyTextColumn”)

数据表不是正如我在其他地方读到的“强类型”,试图强制解决强类型对象的问题。我想从代码隐藏的角度而不是从 XAML 的角度来理解底层机制。从阅读来看,显然你不能直接绑定到数据表,但你可以绑定到 DataTable 对象的“DefaultView”(对我来说没有意义,因为它们指向相同的记录(或记录集,除了说 ;

,在窗口的 XAML 部分,

<src:MyWindow blah, blah >
  <Grid Name="grdTesting">
    <Grid.RowDefinitions>
      <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Label Name="lblMyTextColumn" 
        Content="Just the label" 
        Grid.Row="0" Grid.Column="0 "/>

    <TextBox Name="txtMyTextColumn"
        Grid.Row="0" Grid.Column="1"
        Width="120" />
  </Grid>
</src:MyWindow>

现在,我在代码隐藏中,我读到的是你必须有一个 BindingListCollectionView oView

public partial class MyWindow : Window
{
  BindingListCollectionView oView;
  MyQueryingManager oTestMgr;

  public MyWindow()
  {
    InitializeComponent();

    oTestMgr = new MyQueryingManager();
    DataTable oResults = oTestMgr.GetTheData();

    // Data context for the form bound to the Table retrieved
    oView = new BindingListCollectionView( oResults.DefaultView );

    // One place said the Window should get the binding context
    DataContext = oView;

    // another indicated the grid...  Just need to know which I SHOULD be using
    grdTesting.DataContext = oView;


    // Now, for my binding preparation...
    Binding bindMyColumn = new Binding();
    bindMyColumn.Source = oView;
    bindMyColumn.Path = new PropertyPath("MyTextColumn");
    txtMyTextColumn.SetBinding( TextBox.TextProperty, bindMyColumn );
  }
}

所以 这里……应该是简单,没什么复杂的,我有一个带有记录的数据表,它有一个值。运行表单(无论将上下文绑定到窗口还是网格),并且记录值不会显示在文本框控件中。了解单个文本框上的行为,我可以继续处理所有其他元素(验证、输入掩码、格式设置等),但我被困在这个文本框的门口,

谢谢。

I'm getting started with WPF and finding it difficult to get even the most simple binding working. Here's some givens...

I have an object that queries an existing database and returns a "datatable" object, the data comes back (and for test purposes, only a single row and single column called "MyTextColumn")

The data table is not "Strongly typed" as I've read in other places trying to force the issue of strongly typed objects. I want to understand the underlying mechanisms from the code-behind perspective, AND not from the XAML perspective. From reading, apparently you can't bind directly to a data table, but you can to the "DefaultView" of a DataTable object (makes no sense to me since they point to same record (or set of records, with exception of say a filter of some type).

So, in the XAML portion of the window,

<src:MyWindow blah, blah >
  <Grid Name="grdTesting">
    <Grid.RowDefinitions>
      <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Label Name="lblMyTextColumn" 
        Content="Just the label" 
        Grid.Row="0" Grid.Column="0 "/>

    <TextBox Name="txtMyTextColumn"
        Grid.Row="0" Grid.Column="1"
        Width="120" />
  </Grid>
</src:MyWindow>

So now, I'm in the code-behind, what I've read is you have to have a BindingListCollectionView oView;

public partial class MyWindow : Window
{
  BindingListCollectionView oView;
  MyQueryingManager oTestMgr;

  public MyWindow()
  {
    InitializeComponent();

    oTestMgr = new MyQueryingManager();
    DataTable oResults = oTestMgr.GetTheData();

    // Data context for the form bound to the Table retrieved
    oView = new BindingListCollectionView( oResults.DefaultView );

    // One place said the Window should get the binding context
    DataContext = oView;

    // another indicated the grid...  Just need to know which I SHOULD be using
    grdTesting.DataContext = oView;


    // Now, for my binding preparation...
    Binding bindMyColumn = new Binding();
    bindMyColumn.Source = oView;
    bindMyColumn.Path = new PropertyPath("MyTextColumn");
    txtMyTextColumn.SetBinding( TextBox.TextProperty, bindMyColumn );
  }
}

So... what am I missing here... Should be simple, nothing complex, I have a data table, with a record, that has a value. Run the form (no matter binding context to the Window or the Grid), and the record value does not show in the textbox control. Once I understand the behavior on a single textbox, I can go on with all the other elements (validation, input mask, formatting, etc), but am stuck right at the gate on this one.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

素衣风尘叹 2024-12-09 04:10:54

首先,您可以绑定到DataTable,但您也可以使用默认视图(即DataView)等。

通常,您绑定一个DataTable > 到 ItemsControl 或从它派生的控件,例如 ListBoxDataGrid 等。然后每个容器将获得一个 DataRow(或DataRowView)并且绑定会很容易。

由于您将其直接绑定到 Grid 内的 TextBox,因此您必须在中指定 RowColumn绑定。绑定到第一行中名为“MyTextColumn”的列的正确路径是 Rows[0][MyTextColumn]

尝试此

Binding bindMyColumn = new Binding();
bindMyColumn.Source = oResults;
bindMyColumn.Path = new PropertyPath("Rows[0][MyTextColumn]");
txtMyTextColumn.SetBinding(TextBox.TextProperty, bindMyColumn);

操作 如果您直接绑定到 DataTable 的缺点是它没有实现 INotifyPropertyChanged,因此如果从其他来源更改了该值,UI 将不会知道该值已更改。在这种情况下,您可以使用 DataView 来代替。这里的绑定语法会略有不同,因为您直接使用索引运算符访问 DataRowViews

dataView = oResults.DefaultView;
// Now, for my binding preparation...
Binding bindMyColumn = new Binding();
bindMyColumn.Source = dataView;
bindMyColumn.Path = new PropertyPath("[0][MyTextColumn]");
txtMyTextColumn.SetBinding(TextBox.TextProperty, bindMyColumn);

First, you can bind to a DataTable but you can also use the default view (which is a DataView) etc.

Usually, you bind a DataTable to an ItemsControl or a control that derives from it, such as ListBox, DataGrid etc. Then each container will get a DataRow (or DataRowView) and the binding will be easy.

Since you are binding it directly to a TextBox inside a Grid you would have to specify both Row and Column in the binding. The correct path to bind to the column named "MyTextColumn" in the first row is Rows[0][MyTextColumn]

Try this

Binding bindMyColumn = new Binding();
bindMyColumn.Source = oResults;
bindMyColumn.Path = new PropertyPath("Rows[0][MyTextColumn]");
txtMyTextColumn.SetBinding(TextBox.TextProperty, bindMyColumn);

A problem if you're binding directly to the DataTable is that it doesn't implement INotifyPropertyChanged so the UI won't know that the value has changed if it is changed from some other source. In this case, you can use a DataView instead. The binding syntax will be a little different here since you access the DataRowViews directly with the index operator.

dataView = oResults.DefaultView;
// Now, for my binding preparation...
Binding bindMyColumn = new Binding();
bindMyColumn.Source = dataView;
bindMyColumn.Path = new PropertyPath("[0][MyTextColumn]");
txtMyTextColumn.SetBinding(TextBox.TextProperty, bindMyColumn);
山人契 2024-12-09 04:10:54

网格只是一个布局面板(想想电子表格)。您必须手动将控件放入单元格中。

您正在寻找的可能是一个DataGrid,它能够使用反射自动生成列(或者您可以自己定义它们)。 Microsoft 的 WPF 工具包 提供了一个可供您使用的工具包如果您不想使用众多第三方数据网格控件之一,请使用。

A Grid is simply a layout panel (think spreadsheet). You have to manually place controls into the cells.

What you are looking for is probably a DataGrid, which has the ability to generate columns automatically using reflection (or you can define them yourself). The WPF Toolkit from Microsoft has one you can use if you don't want to go with one of the many 3rd party data grid controls.

雪花飘飘的天空 2024-12-09 04:10:54

您使用的网格是一个布局控件,这意味着它具有作为子项的视觉元素,而不是项目。例如,您应该使用像 Listbox 这样的 ItemsControl,并将 ItemsSource 属性绑定到您的集合。

You are using a Grid which is a layout control, which means that it has visual elements as children, not items. You should use an ItemsControl like Listbox for example, and bind the ItemsSource property to your collection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文