2011-09-19 5 views
1

MVVM 디자인 패턴을 WPF 응용 프로그램에 설정하고 목록 상자 항목을 목록 상자에 추가하는 최선의 방법을 생각하려고합니다. 뷰 모델에서 완료되었습니다. 이 경우에, 나는 붙어있다. 내 메인 윈도우는 usercontrol로서 적절한 뷰를 가져 오는 contentcontrol을 가지고있다. 나는 목록 상자의 itemssource를 viewmodel의 속성에 바인딩해야한다고 가정하고 있지만 카메라보기의 목록 상자에 대한 액세스 권한이 없으므로이를 시도하는 방법을 잘 모르겠습니다.MVVM을 위반하지 않고 ListBox에 항목을 추가하는 방법

동적 데이터가 사용자 컨트롤 작성기의 항목을 가져와야합니까? (틀린 것처럼 보이지만 작동 할 것입니다).

의견이 있으십니까?

사용자 정의 MVVM 패턴이없는 프레임 워크가 사용됩니다.

사용자 컨트롤

<ListBox x:Name="CameraList" Background="#ff4c4c4c" BorderThickness="0" 
ScrollViewer.CanContentScroll="False" TouchEnter="CameraList_TouchEnter" 
TouchLeave="CameraList_TouchLeave" 
ManipulationBoundaryFeedback="CameraList_ManipulationBoundaryFeedback" 
ItemContainerStyle="{DynamicResource ResourceKey=ListBoxItemStyle}" 
PreviewTouchDown="CameraList_PreviewTouchDown" 
PreviewTouchMove="CameraList_PreviewTouchMove" 
PreviewTouchUp="CameraList_PreviewTouchUp" 
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
    <ListBox.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="/ResourceLibrary;component/User 
       Controls/Slider.xaml"> 
       </ResourceDictionary> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </ListBox.Resources> 
</ListBox> 

뷰 모델

class CameraListViewModel : WorkspaceViewModel 
{ 
    #region Fields 
    private readonly CameraRepository cameraRepository; 
    #endregion 


    #region Properties 
    /// <summary> 
    /// Gets and sets the cameras in the system. 
    /// </summary> 
    public ObservableCollection<CameraViewModel> Cameras { get; private set; } 
    #endregion 


    #region Constructors 
    public CameraListViewModel(CameraRepository cameraRepository) 
    { 
     if (cameraRepository == null) 
     { 
      throw new ArgumentNullException("cameraRepository"); 
     } 

     base.DisplayName = "CameraList"; 

     this.cameraRepository = cameraRepository; 

     // Populate the CameraList collection with CameraViewModel. 
     this.CreateCameras(); 
    } 
    #endregion 


    #region Internal Members 
    /// <summary> 
    /// Create all the cameras in the system. 
    /// </summary> 
    private void CreateCameras() 
    { 
     List<CameraViewModel> all = 
      (from cam in cameraRepository.GetCameras() 
      select new CameraViewModel(cam, cameraRepository)).ToList(); 

     foreach (CameraViewModel cvm in all) 
     { 
      cvm.PropertyChanged += this.OnCameraViewModelPropertyChanged; 
     } 

     this.Cameras = new ObservableCollection<CameraViewModel>(all); 
     this.Cameras.CollectionChanged += this.OnCollectionChanged; 
    } 
    #endregion 


    #region Events 
    /// <summary> 
    /// Handle changed collections. 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.NewItems != null && e.NewItems.Count != 0) 
     { 
      foreach (CameraViewModel cvm in e.NewItems) 
      { 
       cvm.PropertyChanged += this.OnCameraViewModelPropertyChanged; 
      } 
     } 

     if (e.OldItems != null && e.OldItems.Count != 0) 
     { 
      foreach (CameraViewModel cvm in e.OldItems) 
      { 
       cvm.PropertyChanged -= this.OnCameraViewModelPropertyChanged; 
      } 
     } 
    } 

    /// <summary> 
    /// Handle property changes. 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private void OnCameraViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     string isSelected = "IsSelected"; 

     // Make sure that the property name we're referencing is valid. 
     // This is a debugging technique, and does not execute in a Release build. 
     (sender as CameraViewModel).VerifyPropertyName(isSelected); 

     // When a camera is selected or unselected, we must let the system know 
     // that properties have changed, so that it will be queried again for a new value. 
     if (e.PropertyName == isSelected) 
     { 
      this.OnPropertyChanged("IsSelected"); 
     } 
    } 
    #endregion 
} 

현재이 작품과 목록 상자가 표시됩니다, 그러나에 camerarepository에 무엇 병합의 좋은 방법이 필요합니다 리스트 박스.

+0

정확합니다.보기 모델에서 수행해야하지만 질문에 대한 충분한 정보를 제공하지 않았습니다. 이 작업을 수행하는 방법은 많이 있지만, MVVM 프레임 워크를 사용하든 관계없이 시스템 설정 방법에 크게 의존합니다. – CodingGorilla

+0

명확히하기 위해 위의 로직을 추가했습니다. – bl4kh4k

+0

MVVM은 Context ... DataContext에 대한 것입니다. 상위 뷰에 ViewModel이 DataContext로 있다고 가정하면 하위 컨트롤 (심지어 UserControls)도 동일한 DataContext를 갖게됩니다 (특별히 다른 것으로 설정하지 않는 한). ListBox ItemsSource를 표시 할 문자열 모음에 간단하게 바인딩 할 수 있어야합니다. – EtherDragon

답변

1

는 사용자가 제공 한 코드 샘플을 바탕으로 당신은 당신의 <ListBox>에 다음을 추가해야합니다 이것은 당신의 CameraListViewModelUserControl의 데이터 컨텍스트, 또는 아마도 Window의 상황이라고 가정

<ListBox ItemsSource="{Binding Path=Cameras}" ...> 

. 그렇지 않은 경우 바인딩의 Source 속성을 설정해야합니다.

카메라를로드하는 생성자를 사용하여 ViewModel을 올바르게 코딩했는지 궁금하다면 제대로 작동한다고 가정 해 보겠습니다.

아직 100 % 확신하지 못해서 귀하의 질문에 답변 해 주시기 바랍니다.

+0

이것은 정확히 내가 뭘 찾고 있는지, 나는 이것이 시작하는 방법에 대한 생각 이었지만 시작하기 전에 피드백이 필요하다고 생각했습니다. :) 모두에게 감사드립니다. – bl4kh4k

관련 문제