简体   繁体   English

WPF将DataTable列绑定到文本框

[英]WPF Binding DataTable column to a textbox

I'm getting started with WPF and finding it difficult to get even the most simple binding working. 我开始使用WPF,发现即使最简单的绑定也很难实现。 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") 我有一个查询现有数据库并返回“数据表”对象的对象,数据返回(出于测试目的,只有一行和一列称为“ 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. 我想从代码隐藏的角度而不是从XAML角度理解底层机制。 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). 通过阅读,显然您不能直接绑定到数据表,但是可以绑定到DataTable对象的“ DefaultView”(对我来说没有意义,因为它们指向相同的记录(或记录集),但某种类型的过滤器)。

So, in the XAML portion of the window, 因此,在窗口的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>

So now, I'm in the code-behind, what I've read is you have to have a BindingListCollectionView oView; 所以现在,我在代码的后面,我读到的是,您必须具有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 谢谢

First, you can bind to a DataTable but you can also use the default view (which is a DataView ) etc. 首先,您可以绑定到DataTable但是也可以使用默认视图(这是DataView )等。

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. 通常,您将DataTable绑定到ItemsControl或从其派生的控件,例如ListBoxDataGrid等。然后,每个容器将获得一个DataRow (或DataRowView ),并且绑定将很容易。

Since you are binding it directly to a TextBox inside a Grid you would have to specify both Row and Column in the binding. 由于直接将其绑定到Grid内的TextBox ,因此必须在绑定中同时指定RowColumn The correct path to bind to the column named "MyTextColumn" in the first row is Rows[0][MyTextColumn] 绑定到第一行中名为“ MyTextColumn”的列的正确路径是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. 如果直接绑定到DataTable则问题在于它没有实现INotifyPropertyChanged因此,如果从其他来源更改了该值,则UI将不知道该值已更改。 In this case, you can use a DataView instead. 在这种情况下,您可以改用DataView The binding syntax will be a little different here since you access the DataRowViews directly with the index operator. 此处的绑定语法会有所不同,因为您可以直接使用索引运算符访问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);

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). 您正在寻找的可能是DataGrid ,它具有使用反射自动生成列的能力(或者您可以自己定义它们)。 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. 如果您不想使用许多第三方数据网格控件之一,则可以使用MicrosoftWPF工具包

You are using a Grid which is a layout control, which means that it has visual elements as children, not items. 您正在使用作为布局控件的Grid,这意味着它具有作为子元素而不是项目的视觉元素。 You should use an ItemsControl like Listbox for example, and bind the ItemsSource property to your collection. 例如,您应该使用类似于Listbox的ItemsControl,并将ItemsSource属性绑定到您的集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM