WPF绑定DataTable列到文本框
我开始使用WPF,发现即使是最简单的绑定工作也很困难。这里有一些让步...WPF绑定DataTable列到文本框
我有一个对象,查询现有的数据库并返回一个“数据表”对象,数据回来(和测试目的,只有一个单一的行和单列称为“MyTextColumn”)
数据表不是“强类型”,因为我在其他地方阅读过试图强制强类型对象的问题。我想从代码隐藏的角度理解底层机制,而不是从XAML的角度来理解。从阅读中,显然你不能直接绑定到数据表,但你可以到DataTable对象的“DefaultView”(对我来说是没有意义的,因为它们指向相同的记录(或记录集,除了说a某种类型的过滤器)。
因此,在窗口的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);
}
}
所以......我错过这里...应该是简单,没有什么复杂的,我公顷拥有一个有价值的记录数据表。运行窗体(无论绑定上下文到窗口或网格),并且记录值不显示在文本框控件中。一旦我理解了单个文本框的行为,我就可以继续使用所有其他元素(验证,输入掩码,格式等),但是我一直坚持在这一个门口。
谢谢
首先,可以绑定到一个DataTable
但也可以使用默认的视图(其是DataView
)等
通常,你绑定DataTable
到ItemsControl
或从它派生的控制,例如作为ListBox
,DataGrid
等,然后每个容器将得到DataRow
(或DataRowView
)和绑定将很容易。
由于您将其直接绑定到Grid
中的TextBox
,因此您必须在绑定中指定和Column
。绑定到第一行命名为“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);
网格只是一个布局面板(认为电子表格)。您必须手动将控件放入单元格中。
你在找什么可能是DataGrid,它有能力使用反射自动生成列(或者你可以自己定义它们)。如果您不想使用众多第三方数据网格控件之一,则可以使用WPF Toolkit from Microsoft。
我熟悉从C#Winforms的DataGrid绑定,如果我想要列式输出没有问题。但是,我希望更多的数据输入编辑具有多个“组”控件。就像一个订单输入系统一样,您将有一个客户名称/地址部分,其他用于计费的部分,以及其他用于评论/注释的部分,例如将出现在发票标题中的信息。一次输入一个条目,从来没有多个记录。 – DRapp
您正在使用网格,它是一个布局控件,这意味着它具有可视元素作为子元素,而不是项目。例如,您应该使用ItemsControl之类的ItemsControl,并将ItemsSource属性绑定到您的集合。
请参阅我在Philipp Schmid下的这个问题/答案组中的评论。 – DRapp
您的解决方案听起来最接近工作,但运行表单时仍然没有输出。我仍在玩弄选项和设置,以查看可能缺失的部分。您将路径引用为“行[0] [MyTextColumn]”似乎不起作用,因为它需要引用DataView,DataView又有DataViewRow对象。所以,我正在调试器中加入我可能会丢失的内容。 – DRapp
@DRapp:如果您使用'DataView'作为源,请参阅我答案的最后部分。路径应该是'“[0] [MyTextColumn]”' –
@DRapp:上传了一个示例应用程序供您查看并与您的尝试进行比较。它的'DataTable'和'DataView'绑定:http://dl.dropbox.com/u/39657172/DataTableBindings.zip –