While an ObservableCollection can be used for this, depending on how it is used you won't recive any benifit from it. The key feature of the ObservableCollection is that it implements INotifyCollectionChanged. What this interface does is provide a notifcation mechanism to tell the UI that a property has changed. Since ObservableCollection already implements this, if you bind your DataGrid, ListBox, ItemsControl, etc.'s ItemSource property to a collection of this type it will automaticly update the UI any time an item is Added/Removed/Replaced/Moved/Reset. Because of this, every time you want to update the collection with a new IEnumerable result set, you will have to first clear the collection, and then add the new results.
However, there is another option that I would recommend over an ObservableCollection in this case. It is to use something called an ObjectDataProvider. Using this we can avoid the code behind entirely, and it is overall much cleaner. So we have our service somewhere, in this case in my Window.xaml.cs
public class TranslationService
{
public IEnumerable<string> Translate(string s)
{
return s.ToCharArray().Select(c => c.ToString());
}
}
Like the service you describe, it takes it a string from a textbox, and returns an IEnumerable. Now, in the XAML we can use this service and make calls to it.
In the window declerations, we add the namespace for where the service is located:
xmlns:local="clr-namespace:WpfApplication4"
Now, in our Window.Resources (Or UserControl, or anywhere else) we can reference our service. Once we have exposed our service as a resource, we can create an ObjectDataProvider that exposes the Translate method we wish to use.
<Window.Resources>
<local:TranslationService x:Key="MyTranslationService" />
<ObjectDataProvider x:Key="MyProvider"
ObjectInstance="{StaticResource MyTranslationService}"
MethodName="Translate">
<ObjectDataProvider.MethodParameters>
""
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
The ObjectDataProvider is keyed to our Service and calls the Translate method with a String parameter. Now all we have to do is get it to respond to our text box.
We can do this by making use of some of the Binding properties. We want our TextProperty in the TextBox to bind to the ObjectDataProvider, so we set the Source property to point to it. The part of the ObjectDataProvider that we want to bind to, in the Path, is the MethodParameter. Now, we set it to Bind directly to the source of that property, and to only travel one way, meaning that the ObjectDataProvider's method parameter won't update the TextBox's text. Finally we can set the UpdateSourceTrigger to PropertyChanged, telling the binding to set the source we are binding to, in the object data provider, whenever there is any change to the text.
<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>
All that's left is to set the ItemsSource in the Grid, or a simple ListBox in this case.
Regarding the final part on the DataGrid:
If you are using the WPFToolkit's data grid, it does have an auto generate feature that can be set through the properties, and you can find more info on it here.