2009-05-19 21 views
0

我的场景: wpf表单有一个文本框和一个wpf工具箱datagrid。 在文本框中输入文本时,我的服务将返回IEnumerable<TranslationItem>项目。我想让我的数据网格显示这个服务的结果。无法将我的头围绕wpf数据绑定

我试过用google搜索,但是我无法得到正面或反面。我只是开始学习WPF,大部分使用的术语都没有涉及到。
我收集的是我应该把我的服务的结果放在ObservableCollection中,而不是汗水。 但是,然后我想以某种方式将其绑定到我的数据网格。我怎样才能做到这一点?网格如何知道要生成哪些列?

回答

0

您将网格的DataSource(甚至是DataContext)设置为您的Observable集合。

我不熟悉那个数据网格,但是大多数网格都有选项可以将Observable Collection中所有类型的公共属性公开为列,或者你明确地在XAML中设置一个列布局,以及列定义是用于列数据的对象的属性。

例如与Infragistics数据网格

   <igDP:Field Name="OrderSize" Label="Order Size"> 
        <igDP:Field.Settings > 
         <igDP:FieldSettings CellWidth="75"> 
          <igDP:FieldSettings.EditorStyle> 
           <Style TargetType="{x:Type Editors:ValueEditor}" > 
            <Style.Setters> 
             <Setter Property="Format" Value="#,##0"/> 
            </Style.Setters> 
           </Style> 
          </igDP:FieldSettings.EditorStyle> 
         </igDP:FieldSettings> 
        </igDP:Field.Settings> 
       </igDP:Field> 

名称是您设置要使用的对象的属性的位置。

0

您的网格可以直接构建列,也可以指定您希望的列类型。如果你看这video,它会解释它。这是针对VS2010的,但VS2008的基本原理是一样的 - 虽然实现只是稍微有点不同,因为它不是完整的。

至于如何绑定,将保存项目的ObservableCollection分配给网格的ItemsSource属性。

3

我收集的是我应该把我的服务的结果放在ObservableCollection中,没有汗水。但后来我想以某种方式将它绑定到我的数据网格。我怎样才能做到这一点?

最简单的方法是将DataGrid的ItemsSource属性设置为ObservableCollection。

网格如何知道要生成哪些列?

DataGrid反映该集合中的对象,并为其找到的每个公共属性创建一个列。有关更多信息,请参见here

如果您直接设置ItemsSource属性,那么它不是真正的wpf绑定。这里有三个我在WPF中开始数据绑定时发现有用的链接。

Bea Stollnitz: What does “{Binding}” mean?
WPF Basic Data Binding FAQ
MSDN: Data Binding How-to Topics

+0

看起来这里有一些很好的阅读。现在没有时间检查它们,但是在我有了之后会回来。 – 2009-05-20 07:19:42

2

虽然可以使用这种一个ObservableCollection,这取决于如何使用它,你将不会从它recive任何中获益, ObservableCollection的关键特性是它实现INotifyCollectionChanged。这个接口做的是提供一个通知机制来告诉UI属性已经改变。因为ObservableCollection已经实现了这个功能,所以如果你将DataGrid,ListBox,ItemsControl等的ItemSource属性绑定到这个类型的集合上,它会在任何时候添加/删除/替换/移动/重置时自动更新UI。因此,每次要使用新的IEnumerable结果集更新集合时,都必须先清除集合,然后添加新结果。

但是,在这种情况下,我建议通过ObservableCollection来推荐另一个选项。它是使用一种称为ObjectDataProvider的东西。使用这个我们可以完全避免背后的代码,并且总体来说更干净。因此,我们有我们的地方服务,在这种情况下,我Window.xaml.cs

public class TranslationService 
{ 
    public IEnumerable<string> Translate(string s) 
    { 
     return s.ToCharArray().Select(c => c.ToString()); 
    } 
} 

像你描述的服务,它需要一个字符串从一个文本框,并返回一个IEnumerable。现在,在XAML中,我们可以使用此服务并调用它。

在窗口declerations,我们增加了在服务所在的命名空间:现在

xmlns:local="clr-namespace:WpfApplication4" 

,我们Window.Resources(或者用户控件,或其他任何地方),我们可以参考我们的服务。一旦我们将我们的服务公开为资源,我们就可以创建一个ObjectDataProvider来公开我们希望使用的Translate方法。

<Window.Resources> 
    <local:TranslationService x:Key="MyTranslationService" /> 
    <ObjectDataProvider x:Key="MyProvider" 
         ObjectInstance="{StaticResource MyTranslationService}" 
         MethodName="Translate"> 
     <ObjectDataProvider.MethodParameters> 
      "" 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 
</Window.Resources> 

ObjectDataProvider被键入我们的服务并使用String参数调用Translate方法。现在我们所要做的就是让它响应我们的文本框。

我们可以通过使用一些绑定属性来做到这一点。我们希望TextBox中的TextProperty绑定到ObjectDataProvider,因此我们将Source属性设置为指向它。我们要绑定到的PathData中的ObjectDataProvider部分是MethodParameter。现在,我们将其设置为直接绑定到该属性的源,并且仅以单向方式传送,这意味着ObjectDataProvider的方法参数不会更新文本框的文本。最后,我们可以将UpdateSourceTrigger设置为PropertyChanged,告诉绑定在对象数据提供程序中设置我们绑定的源,只要文本发生任何更改。

<StackPanel> 
     <TextBox TextChanged="OnTextChanged" 
      Text="{Binding Source={StaticResource MyProvider}, Path=MethodParameters[0], BindsDirectlyToSource=True, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" /> 
     <ListBox ItemsSource="{Binding Source={StaticResource MyProvider}}" /> 
    </StackPanel> 

剩下的就是在网格中设置ItemsSource,或者在这种情况下设置一个简单的ListBox。

关于对DataGrid中的最后一部分: 如果您使用的是WPFToolkit的数据网格,它有一个自动生成功能,可以通过属性进行设置,你可以在它身上找到here更多信息。

+0

谢谢,我想我可以应用这个例子没有什么变化。我不打算直接打电话给我的服务,因为我不想每次击键都触发一个对我的服务(也就是我的翻译数据库)的调用,而是在它们之间有一个小的定时器缓冲区。但除此之外,它看起来很有希望。 – 2009-05-20 12:08:41