虽然可以为此使用 ObservableCollection,但取决于它的使用方式,您不会从中获得任何好处。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 中,我们可以使用该服务并对其进行调用。
在窗口声明中,我们为服务所在的位置添加命名空间:
xmlns:local="clr-namespace:WpfApplication4"
现在,在我们的 Window.Resources(或 UserControl,或其他任何地方)中,我们可以引用我们的服务。一旦我们将服务公开为资源,我们就可以创建一个 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 以我们的 Service 为键,并使用 String 参数调用 Translate 方法。现在我们要做的就是让它响应我们的文本框。
我们可以通过使用一些 Binding 属性来做到这一点。我们希望 TextBox 中的 TextProperty 绑定到 ObjectDataProvider,因此我们将 Source 属性设置为指向它。我们要在 Path 中绑定的 ObjectDataProvider 部分是 MethodParameter。现在,我们将其设置为直接绑定到该属性的源,并且只移动一种方式,这意味着 ObjectDataProvider 的方法参数不会更新 TextBox 的文本。最后,我们可以将 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>
剩下的就是在 Grid 中设置 ItemsSource,或者在本例中设置一个简单的 ListBox。
关于 DataGrid 的最后一部分:如果您使用的是 WPFToolkit 的数据网格,它确实具有可以通过属性设置的自动生成功能,您可以在此处找到更多信息。