2012-02-27 3 views
1

WPF/MVVM을 사용하여 ListBox의 컬렉션에 항목 (내 경우에는 BitmapImage)이 추가되었음을 시각적으로 표시하려고합니다. 배경을 알기 위해 캡처 카드로 스트리밍 비디오를 캡쳐하고 있습니다. 비디오가 스트리밍되는 동안 스틸 이미지를 찍고 있습니다. 이러한 이미지는 UI에서 "스틸 이미지"버튼을 클릭하여 캡처합니다. 이미지를 캡처 한 후 UI의 별도 패널에 해당 이미지의 미리보기 이미지를 표시하고 싶습니다. 이 작업을 수행하기 위해 수행해야 할 작업을 이해하지만 작동시키지 못합니다. 지금, 내 모델은 모든 데이터 검색을 수행합니다.ListBox 바운드 컬렉션으로 업데이트 한 후 UI 새로 고침

public ObservableCollection<BitmapImage> GetAssetThumbnails() 
{ 
    var imageDir = ImgPath != null ? new DirectoryInfo(ImgPath) : null; 
    if(imageDir != null) 
    { 
     try 
     { 
      foreach (FileInfo imageFile in imageDir.GetFiles("*.jpg")) 
      { 
       var uri = new Uri(imageFile.FullName); 
       _assetThumbnails.Add(new BitmapImage(uri)); 
      } 

     } 
     catch (Exception) 
     { 
      return null; 
     } 
    } 

    return _assetThumbnails; 
} 

내 뷰 모델은 생성자에서 모델의 새로운 인스턴스를 만든 다음 _assetModel.GetAssetThumbnails()와 같은 공공 재산 AssetCollection을 설정합니다. ViewModel에는 모든 표준 OnPropertyChanged 이벤트와 이벤트 처리가 있습니다.

private void OnPropertyChanged(string propertyName) 
{ 
    if(PropertyChanged != null) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

#region Public Properties 
public ObservableCollection<BitmapImage> AssetCollection 
{ 
    get { return _assetCollection; } 
    set 
    { 
     if (_assetCollection != value) 
     { 
      _assetCollection = value; 
      OnPropertyChanged("AssetCollection");  
     } 
    } 
} 
#endregion 

private void _assetCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    OnPropertyChanged("AssetCollection"); 
} 
public event PropertyChangedEventHandler PropertyChanged; 

그런 다음 내 XAML 파일에서 ListBox의 항목 소스를 AssetCollection에 바인딩합니다.

<ListBox x:Name="lstBoxAssets" ItemsSource="{Binding AssetCollection}" Grid.Row="1" Background="{DynamicResource GrayColor}" Margin="5,0,0,5" ></ListBox> 

나는 컬렉션의 각 항목이 INotifyPropertyChanged 인터페이스를 구현해야한다는 것을 읽었습니다. 그것을 구현하는 비트 맵 이미지에 대한 래퍼 클래스를 만들려고 했는데도 작동하지 않았습니다. 내가 여기서 누락 된 것이 있습니까? 처음에는 이미지가 표시되지만 이미지를 캡처하여 저장 한 후에는 이미지가 새로 고쳐지지 않습니다. PropertyChanged 이벤트가 발생하지 않아 느낌이 들었습니다. 디버깅을 통해 검사했을 때 항상 null임을 알았으므로 OnPropetyChanged 메서드는 호출되지 않습니다. 어디서이 이벤트 처리기를 추가해야할지 모르겠다. 코드 숨김 파일을 사용하여 뷰 모델의 데이터 컨텍스트를 뷰에 추가하기 만하면됩니다. 그것이 정상적으로 모든 이벤트 처리를 추가 할 것이라고 생각합니다. 누구나 내가 여기서 누락 된 단순한 것을 볼 수 있습니까?

+0

시도해보십시오. "구현 한 비트 맵 이미지에 대한 래퍼 클래스를 만들려고했으나 작동하지 않았습니다." 다시. 항목에 대한 변경 사항은 NotifyPropertyChanged를 통해 항목에서 가져와야합니다. 공공 재산을 사용 했습니까? – Paparazzi

+0

예, 해당 부동산은 공개입니다. 나는 래퍼 클래스를 다시 만들려고 노력할 것이다. 나는 지난 번에 뭔가를 놓친 것 같습니다. – Zajn

답변

2

목록을 업데이트하거나 컬렉션에 저장된 항목을 변경하는 경우 ObservableCollection을 변경 하시겠습니까?

컬렉션 내의 항목을 변경하는 경우 개별 항목이 변경되어 다시 그리기를 할 수 있도록 컬렉션이 변경되었음을 WPF에 알리는 방법을 찾아야합니다.

일반적으로 컬렉션의 항목에는 INotifyPropertyChanged이 구현되어 있으므로 속성이 변경 될 때마다 CollectionChanged 이벤트를 발생 시키도록 WPF에 알리는 목록의 항목에 PropertyChange 알림을 쉽게 첨부 할 수 있습니다.

// Wireup CollectionChanged in Constructor 
public MyViewModel() 
{ 
    ListOfSomeItems = new List<SomeItem>(); 
    AssetCollection.CollectionChanged += AssetCollection_CollectionChanged; 
} 

// In CollectionChanged event, wire up PropertyChanged event on items 
void AssetCollection_CollectionChanged(object sender, CollectionChangedEventArgs e) 
{ 
    if (e.NewItems != null) 
    { 
     foreach(Asset item in e.NewItems) 
      item.PropertyChanged += Asset_PropertyChanged; 
    } 
    if (e.OldItems != null) 
    { 
     foreach(Asset item in e.OldItems) 
      item.PropertyChanged -= Asset_PropertyChanged; 
    } 
} 

// In PropertyChanged, raise CollectionChanged event 
void Asset_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    OnPropertyChanged("AssetCollection"); 
} 

항목이 INotifyPropertyChanged를 구현하지 않는 경우, 수동으로 수집 변경에 따라 CollectionChanged 이벤트 언제에게 항목을 제기해야합니다. 어딘가에 우리가 볼 수없는 구문 오류가있을 수 있습니다처럼

AssetCollection[0].Thumbnail = new BitmapImage(uri); 
OnPropertyChanged("AssetCollection"); 

당신이/추가 항목을 제거하여 ObservableCollection 자체를 변경하고 UI 업데이트가 표시되지 않는 경우, 다음이 울립니다.

가장 일반적으로 보게되는 것은 공개 속성이 아닌 개인 속성을 변경하는 것입니다.

// Will not raise the CollectionChanged notification 
_assetCollection = _assetModel.GetAssetThumbnails(); 

// Will raise the CollectionChanged notification 
AssetCollection = _assetModel.GetAssetThumbnails(); 

나는 또한 CollectionChanged 이벤트를 발생시키지 않습니다뿐만 아니라 대신 ObservableCollectionList 또는 사용자 지정 컬렉션을 사용하는 사람들을 많이 볼 수 있지만.

+0

음, 새 이미지를 캡처하면 ObservableCollection의 이미지가 저장되는 디렉토리와 동일한 디렉토리에 저장됩니다. 따라서 컬렉션 자체가 아니라 항목을 변경할 필요가 있다고 생각합니다. 당신의 예제는 매우 도움이되었습니다, 감사합니다! 내가 열거 한 몇 가지 변경을 시도하고 그들이 작동하는지 확인하려고합니다. – Zajn

+0

나는 이것이 내 코드에서 잘못하고있는 것을 이해하는 데 도움이되므로 이것을 대답으로 받아 들일 것입니다. 아직 UI를 제대로 업데이트 할 수 없었지만 축소판을 만든 후에 발생하는 이벤트와 관련이 있으므로이 질문의 범위를 벗어납니다. – Zajn

관련 문제