2012-06-26 4 views
0

я в настоящее время есть несколько объектов модели следующим образом:Синхронизация ObservableCollection в ViewModel к ObservableCollection (одного типа) в модели

public class ModelBaseClass : INotifyPropertyChanged 
{ 
    //Members omitted for brevity, but there is a DateTime property 
    //that becomes important further down (see dummy method in application controller)  
} 

и другое:

public class ModelCollectionClass : INotifyPropertyChanged 
{ 
    private ObservableCollection<ModelBaseClass> modelBaseClasses; 
    public ObservableCollection<ModelBaseClass> ModelBaseClasses 
    { 
     get { return modelBaseClasses; } 
     set 
     { 
      modelBaseClasses = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("ModelBaseClasses"); 
     } 
    } 

    private void modelBaseClasses_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     OnPropertyChanged(new PropertyChangedEventArgs("ModelBaseClasses")); 
    } 
} 

Тогда в одном из моего взгляда-х view-model, у меня есть такие наблюдаемые коллекции:

private ObservableCollection<ModelBaseClass> modelBaseClasses; 
public ObservableCollection<ModelBaseClass> ModelBaseClasses 
{ 
    get{ return modelBaseClasses ?? (modelBaseClasses = new ObservableCollection<ModelBaseClass>()); } 
    set 
    { 
     modelBaseClasses = value;     
     OnPropertyChanged(new PropertyChangedEventArgs("ModelBaseClasses")); 
    } 
}  

private ObservableCollection<ModelCollectionClass> modelCollectionClasses; 
public ObservableCollection<ModelCollectionClass> ModelCollectionClasses 
{ 
     get { return modelCollectionClasses ?? (modelCollectionClasses = new ObservableCollection<ModelCollectionClass>()); } 
     set 
     { 
      modelCollectionClasses = value; 
      OnPropertyChanged(new PropertyChangedEventArgs("ModelCollectionClasses"));     
     } 
}  

Тогда в моем контроллере приложений (Делегаты работают, чтобы посмотреть-моделей), у меня есть фиктивный метод, который загружает коллекцию ModelBaseClass как следующим образом:

for (int i = 0; i < 8; i++) 
{ 
    myViewModel.ModelBaseClasses.Add(new ModelBaseClass() 
    { 
     DateTimeProperty = Convert.ToDateTime("06/2" + i + "/2012 09:00:00 AM") 
     //Other properties get set as well, using the i variable... 
    } 
} 

Следует отметить, что существует более чем один для петель в этом методе, так что я могу иметь много данных для работы.

Далее, у меня есть метод, который принимает эту большую коллекцию предметов и группирует их по дате, как следует:

myViewModel.ModelBaseClasses 
       .GroupBy(modelBaseClass => ((DateTime)modelBaseClass.DateTimeProperty).Date) 
       .Select(group => group.ToList()) 
       .ToList() 
       .ForEach(
        list => myiewModel.ModelBaseCollections.Add(new ModelBaseCollection() { ModelBaseClasses = new ObservableCollection<ModelBaseClass>(list) }) 
       ); 

Теперь это, где он начинает получать более сложным. В XAML моего представления у меня есть ItemControl, объявленный с его ItemsSource, связанным с свойством ModelCollectionClasses в моей модели представления. Это выглядит следующим образом:

<ItemsControl ItemsSource="{Binding Path=DataContext.ModelCollectionClasses, RelativeSource={RelativeSource AncestorType={x:Type views:MyView}}}" 
           ItemTemplate="{StaticResource ItemsTemplate}">      
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Width="{Binding ElementName=scroller, Path=ViewportWidth}"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

Тогда в словаре ресурсов для этой конкретной точки зрения, у меня есть DataTemplate объявлен как следующим образом:

<DataTemplate x:Key="ItemsTemplate"> 
    <Grid DataContext="{Binding ModelBaseClasses}">    

     <DataGrid AutoGenerateColumns="False" 
        HeadersVisibility="None" 
        CanUserAddRows="False" 
        CanUserDeleteRows="False" 
        ItemsSource="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" 
        SelectedItem="{Binding Path=DataContext.SelectedModelBaseClass, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type views:MyView}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">     

      <DataGrid.Columns>           
        ...Omitted for brevity... 
      </DataGrid.Columns> 
     </DataGrid>    
    </Grid> 
</DataTemplate> 

Теперь, когда все, что сказал, я получаю желаемое визуальное представление данных, которые я изначально хотел. Однако проблема, с которой я сейчас сталкиваюсь, - это когда я хочу удалить один из объектов ModelBaseClass. Поскольку ItemsSource DataGrid привязан к свойству ModelBaseClasses ModelCollectionClass, а не ModelBaseClasses в моей модели представления, тогда, когда я удаляю ModelBaseClass из ModelCollectionClass, найденного в моей модели представления, мне нужно как-то уведомить ModelCollectionClass о это изменение также позволяет обновить пользовательский интерфейс.

Я видел несколько других примеров, когда некоторые люди создавали классы-оболочки для синхронизации коллекций моделей и коллекций моделей представлений, но мне очень сложно пытаться реализовать такую ​​вещь с помощью собственного приложения. Будем очень благодарны за любые идеи или полезные советы/идеи.

+1

Вы уверены, что кто-нибудь проанализирует этот большой кусок кода для вас? Старайтесь быть лаконичными. – RredCat

+0

Я знаю, что это совсем немного кода, но я стараюсь быть максимально прозрачным. Спасибо, что посмотрели. – dgsmith15

+0

Было бы интересно посмотреть, как вы удаляете ModelBaseClass, но если я правильно понял, вам следует поднять NotifyPropertyChanged для вашего ModelBaseClass и ModelCollectionClass. – BigL

ответ

0

Честно говоря, ваш вопрос настолько сложный, что я не уверен, что получаю то, что вы хотите сделать. Но я заметил одну вещь в вашем коде: в ModelCollectionClass вы установили ModelBaseClass, но сообщите, что вы установили ModelBaseClasses (es). Не уверен, что это поможет.

+0

Это была опечатка. Позвольте мне попытаться обобщить: ModelCollectionClass имеет OC , называемый ModelBaseClasses. MyViewModel имеет OC (также), называемый ModelBaseClasses, и заполняется вручную в контроллере приложения. MyViewModel OC называется ModelCollectionClasses и заполняется контроллером приложения с помощью ModelBaseClasses из viewmodel. Я могу удалить объекты ModelBaseClass из ModelBaseClasses в VM, но вам необходимо уведомить ModelBaseClasses в ModelCollectionClass об этом изменении, так как пользовательский интерфейс привязан к нему, а не ModelBaseClasses в viewmodel. – dgsmith15

Смежные вопросы