Связывание ListBox с глобальным индексом - PullRequest
1 голос
/ 26 сентября 2011

В моем приложении есть пара ObservableCollections, одна из которых вложена в элемент другой. Каждый из них содержит несколько полей, например

ObservableCollectionA (называемые списки)

  • Название
  • Описание
  • Адрес
  • Изображения как MediaItems

ObservableCollectionB (называется MediaItems)

  • ImageName
  • Src
  • DisplayTime

В настоящее время я обращаюсь к ObservableCollections следующим образом:

Listings(0).MediaItems(0).ImageName

Мое приложение имеет главное окно отображения элементов из списков и UserControl, который содержит ListBox, который отображает элементы из MediaItems.

В настоящее время мое окно связано с листингами с использованием кода в методе New:

Dim AppLocal As Program = Application.CurrentItem
AppLocal.CurrentItem = 0
Me.DataContext = Listings.Item(AppLocal.CurrentItem)

Для Списков ObservableCollection, UserControl имеет XAML DataContext, который ссылается на локальный метод, который извлекает записи из вложенной MediaItems ObservableCollection.

<UserControl.DataContext>
    <ObjectDataProvider ObjectType="{x:Type local:ThumbImageLoader}" MethodName="LoadImagesv2" IsAsynchronous="True"  />
</UserControl.DataContext>
<Grid x:Name="ThumbListBoxGrid">
    <ListBox x:Name="ThumbListBox" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" />
</Grid>

Метод здесь:

Public NotInheritable Class ThumbImageLoader
Public Shared Function LoadImagesv2() As List(Of MediaItems)

    Dim AppLocal As Program = Application.Current

    Dim ThumbImages As New List(Of MediaItems)

    ThumbImages = Listings(AppLocal.CurrentItem).MediaItems

    Return ThumbImages
End Function
End Class

При разработке макета пользовательского интерфейса я только что связывал первый элемент (индекс 0). Теперь я хочу иметь возможность устанавливать AppLocal.CurrentItem из любой точки приложения, чтобы обновлялись окно и список.

В идеале мне бы хотелось, чтобы при изменении индекса глобального свойства пользовательский интерфейс обновлялся.

Как мне это сделать?

Есть ли лучший способ сделать это?

Ben

Ответы [ 2 ]

1 голос
/ 26 сентября 2011

Хорошо, я обнаружил радость CollectionView.Предлагал именно то, что мне было нужно, и было невероятно легко реализовать.Я был поражен не только тем, насколько легко это реализовать, но мне удалось вырезать больше строк кода, чем я использовал для его реализации.

Я реализовал общедоступный CollectionViewSource

Public ListingDataView As CollectionViewSource

В моем главном окне я реализовал его следующим образом:

<CollectionViewSource x:Key="ListingDataView" />

и привязал к нему свою сетку верхнего уровня:

<Grid DataContext="{Binding Source={StaticResource ListingDataView}}">

В моем запуске приложения я установил Source CollectionView

AppLocal.ListingDataView = CType(Application.Current.MainWindow.Resources("ListingDataView"), CollectionViewSource)
AppLocal.ListingDataView.Source = Listings

Следующая часть, которая произвела на меня наибольшее впечатление, - это реализация моего пользовательского элемента управления.Я вспомнил, что UserControl наследуется от главного окна, поэтому у него уже есть доступ к CollectionView, поэтому я выбрал отдельную привязку класса и метода в пользу этого:

<ListBox ItemsSource="{Binding Path=MediaItems}" VerticalAlignment="Top" IsSynchronizedWithCurrentItem="True" />

Теперь, когда я хочу установить CurrentИндекс списка, я просто называю это:

AppLocal.ListingDataView.View.MoveCurrentToPosition(AppLocal.CurrentProperty)

Через несколько миллисекунд пользовательский интерфейс обновляется автоматически.

Готово !!

0 голосов
/ 26 сентября 2011

Если вы хотите, чтобы несколько исходных данных (например, свойства вашей наблюдаемой коллекции и индекс для наблюдаемой коллекции) для одной цели, вы должны использовать MultiBinding.

Так что в вашем случае что-то вроде этого должно помочь ...

<ListBox x:Name="ThumbListBox" IsSynchronizedWithCurrentItem="True" >
   <ListBox.ItemsSource>
      <MultiBinding Converter="{StaticResource CollectionAndIndexCollaborator}">
           <Binding Path="Listings" />
           <Binding Path="Application.CurrentItem.CurrentItem" />
      </MultiBinding> 
   </ListBox.ItemsSource>
</ListBox>

при условии, что ....

  1. Ваш контекст данных - это некоторый класс, который содержит объект Application через свойство с тем же именем Application и коллекцию Listings через свойство с тем же именем Listings.
  2. В вашем классе DataContext и Application должен быть реализован INotifyPropertyChanged. Он также должен вызывать уведомления для Application и Setter свойств CurrentItem и CurrentItem.CurrentItem.
  3. CollectionAndIndexCollaborator.Convert() метод возвращает то же индексированное значение, что и итоговая коллекция ....

    возврат ((ObservableCollection) значений [0]). Item (int.Parse (values ​​[1]));

где предполагается, что MyListingType - это T вашей Listings коллекции.

Таким образом, когда кто-либо изменяет глобальное Application.CurrentItem.CurrentItem, вышеприведенное мульти-связывание получит уведомление и выберет необходимый элемент Listings.

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