Хотя для этого можно использовать коллекцию ObservableCollection, в зависимости от того, как она используется, вы не получите от нее никаких выгод. Ключевой особенностью ObservableCollection является то, что она реализует INotifyCollectionChanged. Этот интерфейс предоставляет механизм уведомлений, чтобы сообщить UI, что свойство изменилось. Поскольку ObservableCollection уже реализует это, если вы связываете свойство ItemSrid, ListBox, ItemsControl и т. Д. ItemSource с коллекцией этого типа, оно будет автоматически обновлять пользовательский интерфейс при каждом добавлении / удалении / замене / перемещении / сбросе элемента. Из-за этого каждый раз, когда вы хотите обновить коллекцию новым набором результатов 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 связан с нашим Сервисом и вызывает метод Translate с параметром String. Теперь все, что нам нужно сделать, это заставить его ответить на наше текстовое поле.
Мы можем сделать это, используя некоторые свойства Binding. Мы хотим, чтобы наш TextProperty в TextBox связывался с ObjectDataProvider, поэтому мы устанавливаем свойство Source, чтобы указывать на него. Часть ObjectDataProvider, которую мы хотим связать в Path, это 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>
Осталось только установить ItemsSource в Grid или простой ListBox в этом случае.
Относительно заключительной части в DataGrid:
Если вы используете сетку данных WPFToolkit, у нее есть функция автоматического создания, которую можно установить через свойства, и вы можете найти больше информации об этом здесь .