Понимание привязки данных - PullRequest
2 голосов
/ 23 января 2012

Я новичок в WPF и всей связи с данными.Я прочитал пару постов, и я совершенно не уверен, как связать свои данные с элементом пользовательского интерфейса.

Я видел пост, делающий это следующим образом:

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Name="myWindow">
   <Grid>
       <TextBox Text="{Binding Path=Speed, ElementName=myWindow}" />
   </Grid>
</Window>

Это предполагает Speed - это свойство / элемент, определенный в файле code-behind.Несколько других людей назвали привязку, используя статический ресурс , и ссылаются на эту и другие, названные DataContext, которые будут использоваться для привязки.Теперь, поскольку я новичок в связывании данных в WPF, я совершенно не уверен, существует ли какой-либо метод наилучшей практики для использования связывания данных.

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

Я стремлюсь иметь только файл XAML, без необходимости добавлять что-либо в файл кода * .xaml.cs.Например: у меня есть класс с именем MainWindowViewModel (который будет представлять мою ViewModel), имеющий член типа ObservableCollection<string>, и я хочу связать ListBox (в моем представлении) с этой коллекцией.Пока я работал только так, используя первый случай, ElementName, где я должен добавить свойство к классу представления как своего рода соединитель.Вот так:

MainWindow.xaml:

<Window x:Class="Sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Name="MW" Title="MainWindow" Height="419" Width="463">
    <Grid>
        <ListBox ItemsSource="{Binding ElementName=MW, Path=ListerResultConnector}" />
    </Grid>
</Window>

MainWindow.xaml.cs:

private ObservableCollection<string> mListerResultData = MainWindowViewModel.Instance.RetrievalStringResults;
public ObservableCollection<string> ListerResultConnector
{
    get { return mListerResultData; }
}

Мой вопрос: существует ли более разумный способ привязкиданные для моего пользовательского интерфейса, использующие в качестве дополнительного свойства «соединитель» в файле с выделенным кодом.

Ответы [ 6 ]

2 голосов
/ 23 января 2012

Ваш ViewModel должен быть установлен как DataContext для представления.Тогда вам не нужен «дополнительный соединитель» в коде позади.Связывание на самом деле относится к DataContext, и если вы его не установите, оно останется как «this», что соответствует вашему файлу codebehind (который является лишь частичным для вашего представления).

Кроме того, взгляните на: Приложения WPF с шаблоном проектирования Model-View-ViewModel

Сначала вы должны получить WPF и его основы связывания, но как только вы их поймете, я предлагаю взглянуть на Caliburn Micro и его привязки на основе соглашений, обработка событий и другие функции, которые делают ваш код намного чище.

1 голос
/ 23 января 2012

Да, связывание ничего, если не смущает.

Этот пример из msdn может быть полезным.Обратите внимание, как DataContext объявляется на Window "уровне" - в данном случае это сложный / составной объект, и поэтому описания {Binding} подэлементов Window неявно связаны с "Родительским уровнем" DataContext.

Основное преимущество, которое мы получаем, заключается в том, что когда DataContext устанавливается для данного объекта, все привязки данных «подэлемента» автоматически синхронизируются.Мы можем управлять этой синхронизацией на любом / многих уровнях иерархии структуры управления пользовательским интерфейсом, используя этот шаблон.

Связывание коллекции под капотом

Суть в том, что ваша коллекциядолжен реализовать IList как минимум.Многие классы .NET Collection «готовы к связыванию».

Вот цитата из msnd doc на ObservableCollection :

Перед реализацией своей собственной коллекции, подумайте об использованииObservableCollection или один из существующих классов коллекций, таких как List, Collection и BindingList, среди многих других.Если у вас есть продвинутый сценарий и вы хотите реализовать свою собственную коллекцию, рассмотрите возможность использования IList, который предоставляет не универсальную коллекцию объектов, к которой индексируется индивидуальный доступ.Реализация IList обеспечивает наилучшую производительность с механизмом привязки данных.

Наконец, Список связывания IB против IList необходим для двусторонней привязки.

1 голос
/ 23 января 2012

Самый простой способ сделать это будет:

<Window x:Class="WpfApplication4.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ctrl="clr-namespace:WpfApplication4"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <ctrl:MainWindowViewModel x:Key="mym" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource mym}}">
    <ListBox ItemsSource="{Binding Path=MyListProp}" />
</Grid>

В приведенном выше примере выполняется следующее:

  1. Создает новый объект ViewModelокно как ресурс для вас
  2. Назначает модель представления как DataContext для окна (более точно для корневой сетки)
  3. Привязывает поле списка к вашему свойству ViewModel ObservableCollection MyListProp.

Попытайтесь ознакомиться со свойствами связующего класса, чтобы полностью понять этот пример, используя библиотеку msdn.Также WPF 4 Unleashed - Адам Натан - отличный ресурс для начинающего wpf.Глава 13 - Привязка данных должна охватывать все, что вы можете знать о привязках.

1 голос
/ 23 января 2012

Привязка обычно состоит из двух частей: исходного объекта и имени свойства

Когда вы указываете ElementName в привязке, вы устанавливаете исходный объект.Другие способы указать исходный объект привязки включают свойства RelativeSource и Source.Вы также можете оставить исходный объект привязки неопределенным, в этом случае он будет использовать любой DataContext текущего объекта.Исходный объект может быть элементом пользовательского интерфейса, найденным в VisualTree WPF, или может быть объектом класса, который находится в DataContext

элемента управления. Когда вы указываете Path, вы сообщаете привязке, какое свойство использовать,Вы также можете оставить это свойство пустым для привязки к текущему объекту DataContext

DataContext - это объект данных, хранящийся за элементом управления.Обычно это Model или ViewModel (при использовании MVVM), хотя это может быть также практически любой объект, например элемент пользовательского интерфейса.

В вашем примере

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Name="myWindow">
   <Grid>
       <TextBox Text="{Binding Path=Speed, ElementName=myWindow}" />
   </Grid>
</Window>

вы указываете привязке, что его исходный объект является элементом пользовательского интерфейса в визуальном дереве с именем myWindow, а свойство называется Speed.Поскольку ваш объект с именем myWindow имеет тип Window, эта привязка будет работать только в том случае, если ваш класс Window действительно имеет свойство с именем Speed.

Здесь есть много ответов, предлагающих вам переключитьсяиспользовать шаблон проектирования MVVM, и я согласен, что вы должны попробовать использовать MVVM, если вы работаете с WPF.Это значительно упрощает кодирование, поскольку вы отделяете логику приложения от вашего пользовательского интерфейса.Если вам интересно, у меня есть простой пример MVVM, опубликованный в моем блоге , который объясняет основы этого шаблона проектирования.

1 голос
/ 23 января 2012

Вы должны использовать отдельный класс ViewModel (WindowViewModel), который представляет ваш контекст данных для вашего окна (Window.DataContext).

Я обнаружил, что использование инструментария MVVM Light и просмотр некоторых видеороликов на сайте помогли мне заполнить пробелы.Найдите время, чтобы изучить его, прежде чем приступить к работе, и он начнет погружаться. Контейнеры IoC также смешаны с MVVM + WPF для управления каталогами и управления временем жизни моделей представлений и улучшения опыта разработки ( blendability ).

Наборы инструментов не требуются и иногда мешают изучению шаблона.Как только вы поймете это, вы должны использовать инструментарий для ускорения процесса разработки.Вот сравнение различных наборов инструментов MVVM .

1 голос
/ 23 января 2012

Ваш {Binding ElementName=MW означает, что вы привязываетесь к самому окну, поэтому ваш DataContext является окном, и любые свойства, которые вы реализуете, должны быть определены в этом окне (в вашем коде позади - ваши "соединители").

Вам необходимо удалить бит ElementName=MW и назначить вашу ViewModel как DataContext, чтобы вы могли напрямую связываться с его свойствами. Как это сделать, зависит от того, используете ли вы «ViewModel First» или «View First»

Сначала в представлении вы вручную назначаете DataContext для представления в коде при создании представления.

Сначала в ViewModel вы создаете шаблон данных в XAML, который связывает ваше представление с определенной моделью представления. Я думаю, что сначала ViewModel является более распространенным. Ссылка, которую опубликовал Дарьян, должна помочь вам понять разницу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...