2011-08-30 115 views
0

我开始使用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); 
    } 
} 

所以......我错过这里...应该是简单,没有什么复杂的,我公顷拥有一个有价值的记录数据表。运行窗体(无论绑定上下文到窗口或网格),并且记录值不显示在文本框控件中。一旦我理解了单个文本框的行为,我就可以继续使用所有其他元素(验证,输入掩码,格式等),但是我一直坚持在这一个门口。

谢谢

回答

1

首先,可以绑定到一个DataTable但也可以使用默认的视图(其是DataView)等

通常,你绑定DataTableItemsControl或从它派生的控制,例如作为ListBoxDataGrid等,然后每个容器将得到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); 
+0

您的解决方案听起来最接近工作,但运行表单时仍然没有输出。我仍在玩弄选项和设置,以查看可能缺失的部分。您将路径引用为“行[0] [MyTextColumn]”似乎不起作用,因为它需要引用DataView,DataView又有DataViewRow对象。所以,我正在调试器中加入我可能会丢失的内容。 – DRapp

+0

@DRapp:如果您使用'DataView'作为源,请参阅我答案的最后部分。路径应该是'“[0] [MyTextColumn]”' –

+0

@DRapp:上传了一个示例应用程序供您查看并与您的尝试进行比较。它的'DataTable'和'DataView'绑定:http://dl.dropbox.com/u/39657172/DataTableBindings.zip –

0

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

你在找什么可能是DataGrid,它有能力使用反射自动生成列(或者你可以自己定义它们)。如果您不想使用众多第三方数据网格控件之一,则可以使用WPF Toolkit from Microsoft

+0

我熟悉从C#Winforms的DataGrid绑定,如果我想要列式输出没有问题。但是,我希望更多的数据输入编辑具有多个“组”控件。就像一个订单输入系统一样,您将有一个客户名称/地址部分,其他用于计费的部分,以及其他用于评论/注释的部分,例如将出现在发票标题中的信息。一次输入一个条目,从来没有多个记录。 – DRapp

0

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

+0

请参阅我在Philipp Schmid下的这个问题/答案组中的评论。 – DRapp