2009-05-19 1 views
0

Мой сценарий: Форма wpf имеет текстовое поле и инструментарий wpf datagrid. Когда текст введен в текстовое поле, моя служба возвращает IEnumerable<TranslationItem> элементов. Я хочу, чтобы мой datagrid показывал результат этой службы.Невозможно обернуть голову вокруг привязки wpf

Я пробовал искать походы, но я не могу получить к нему головы или хвосты. Я только начинаю изучать WPF, и большинство используемых терминов ускользают от меня.
То, что я собираюсь, это то, что я должен поместить результат моего сервиса в ObservableCollection, без пота. Но тогда я хочу как-то привязать его к моему datagrid. Как я могу это сделать? Как сеть узнает, какие столбцы будут генерироваться?

ответ

0

Вы устанавливаете DataSource (или даже DataContext) сетки в свою Наблюдаемую коллекцию.

Я не знаком с этой сеткой данных, но в большинстве сеток есть варианты либо выставлять все публичные свойства типа в 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 DataGrid на ObservableCollection.

Как будет знать, какие столбцы будут генерироваться сетью?

DataGrid отражает объекты в этой коллекции и создает столбец для каждого найденного им публичного имущества. См. here для получения дополнительной информации.

Если вы установили свойство ItemsSource напрямую, это не действительно привязка wpf. Вот три ссылки, которые я нашел полезными, когда я начал привязывать данные в WPF.

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

+0

Похоже, здесь есть хорошее чтение. У меня нет времени, чтобы проверить их сейчас, но вернусь после того, как у меня есть. –

2

Хотя ObservableCollection может использоваться для этого, в зависимости от того, как она используется не будет никакого benifit Получать от него. Ключевой особенностью ObservableCollection является то, что он реализует INotifyCollectionChanged. Что делает этот интерфейс, так это механизм уведомления о том, что пользовательский интерфейс изменил свойство.Поскольку ObservableCollection уже реализует это, если вы привязываете свойство ItemSource DataGrid, ListBox, ItemsControl и т. Д. К коллекции этого типа, он автоматически обновляет пользовательский интерфейс в любое время, когда элемент будет добавлен/удален/заменен/перемещен/сброс. Из-за этого каждый раз, когда вы хотите обновить коллекцию новым набором результатов 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 (или UserControl, или в другом месте), мы можем ссылаться на наш сервис. После того как мы разоблачили нашу службу как ресурс, мы можем создать ObjectDataProvider, который предоставляет метод перевода, который мы хотим использовать.

<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. Теперь все, что нам нужно сделать, это заставить его ответить на наше текстовое поле.

Мы можем сделать это, используя некоторые свойства связывания. Мы хотим, чтобы наш TextProperty в TextBox связывался с ObjectDataProvider, поэтому мы установили свойство Source для указания на него. Часть объекта ObjectDataProvider, который мы хотим связать, в Пути, является MethodParameter. Теперь мы привязываем его к Bind непосредственно к источнику этого свойства и только перемещаемся в одну сторону, а это означает, что параметр метода 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 в сетке, или простой ListBox в данном случае.

Что касается заключительной части на DataGrid: При использовании сетки данных в WPFToolkit, он имеет автоматический генерировать функцию, которая может быть установлена ​​через свойство, и вы можете найти более подробную информацию о нем here.

+0

Спасибо, я думаю, что могу применить этот пример с небольшими изменениями. Я не буду называть свою услугу напрямую, так как мне не хотелось бы, чтобы каждое нажатие клавиши вызывало вызов моей услуги (и, следовательно, мой перевод db), но между ними был небольшой буфер таймера. Но кроме этого он выглядит обещающим. –