2010-06-16 4 views
2

Я создал ObservableCollection в коде, находящемся под контролем пользователя. Она создается, когда окно нагрузки:WPF ObservableCollection в xaml

private void UserControl_Loaded(object sender, RoutedEventArgs e) 
    { 
     Entities db = new Entities(); 
     ObservableCollection<Image> _imageCollection = 
     new ObservableCollection<Image>(); 

     IEnumerable<library> libraryQuery = 
     from c in db.ElectricalLibraries 

     select c; 

     foreach (ElectricalLibrary c in libraryQuery) 
     { 
      Image finalImage = new Image(); 
      finalImage.Width = 80; 

      BitmapImage logo = new BitmapImage(); 
      logo.BeginInit(); 
      logo.UriSource = new Uri(c.url); 
      logo.EndInit(); 

      finalImage.Source = logo; 

      _imageCollection.Add(finalImage); 

     } 

    } 

Мне нужно, чтобы получить ObservableCollection изображений, которые создаются на основе URL, сохраненной в базе данных. Но мне нужно ListView или другой ItemsControl связываться с ним в XAML файл следующим образом:

Но я не могу понять, как передать ObservableCollection к ItemsSource этого контроля. Я попытался создать класс, а затем создать экземпляр класса в файле xaml, но он не сработал. Должен ли я создать статический ресурс как-то>

Любая помощь будет принята с благодарностью.

ответ

4

Во-первых, ObservableCollection является локальной переменной. Вам нужно сделать это как частную глобальную переменную и разоблачить ее публичным свойством. Вы можете использовать интерфейс INotifyPropertyChanged, чтобы автоматически обновлять данные изображения, когда сама фактическая коллекция изменяется.

В вашем XAML вам необходимо установить DataContext для себя, и вы можете напрямую связать свое публичное свойство с ItemsSource. Вы можете использовать ItemTemplate для отображения элементов по-своему.

Приветствия, Adam

Пример в соответствии с просьбой:

В C#:

public MyWindowClass 
{ 
    public ObservableCollection<image> MyImageCollection 
    { 
    get; 
    set; 
    } 
} 

В XAML:

<UserControl 
... 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

... 
<ListBox ItemsSource="{Binding MyImageCollection}" ItemTemplate="*yourtemplateresource*" /> 
... 

</UserControl> 

Теперь, причина того, что я уже с помощью INotifyPropertyChanged является что если вы попробуете:

MyImageCollection = new ObservableCollection<image>(); 

Элементы в списке не будут автоматически обновляться. Однако с ObservableCollection вы делаете не необходимо реализовать INotifyPropertyChanged для основного добавления и удаления элементов списка.

+1

Технически правильно, за исключением того, что вы можете добавить более подробную информацию и исправить одну маленькую точку - * ObservableCollection * уже реализует * INotifyCollectionChanged * и * INotifyPropertyChanged *, поэтому нет необходимости переопределять/вызывать их в общедоступном объявлении. – slugster

+0

Благодарим вас за помощь. Не могли бы вы предоставить какие-нибудь небольшие снайперы кода в качестве примера? – Enzomatric

+0

@slugster - извините, что неясно в моем ответе. Причина, по которой я упомянул INotifyPropertyChanged, состояла в том, чтобы просто обновить список, если собственная публичная собственность автора была повторно инициализирована. Я, вероятно, не должен был добавлять эту излишнюю информацию ... @Cloverness - пример добавления ... –

1

Вы должны установить DataContext в UserControl вашей коллекции:

DataContext = _imageCollection 

Вы можете сделать это в методе UserControl_Loaded().

Далее вам нужно связать ItemsSource из ListView в XAML:

<ListView ItemsSource="{Binding}"/> 

The {Binding} эквивалентно {Binding .}, который связывается с DataContext в UserControl.Если вам нужно «больше вещей» в вашем DataContext вы можете вместо этого создать класс вроде этого:

class ViewModel : INotifyPropertyChanged { 
    public ObservableCollection Images { get { ... } } 
    ... 
} 

Используйте этот класс для DataContext:

DataContext = new ViewModel(); 

И заменить связывание связываться с Images собственности :

<ListView ItemsSource="{Binding Images}"/> 

Затем вы можете добавить еще одно свойство ViewModel:

class ViewModel : INotifyPropertyChanged { 
    public ObservableCollection Images { get { ... } } 
    public String Message { get { ... } set { ... } } 
    ... 
} 

и привязать его к элементу управления:

<TextBlock Text="{Binding Message}"/> 

Помните уволить PropertyChanged событие, когда свойство Message изменяется в ViewModel. Это приведет к обновлению пользовательского интерфейса при изменении свойств модели представления с помощью кода.

+0

Большое спасибо. Теперь у меня другая проблема в моем коде. – Enzomatric