2010-03-21 7 views
3

Je maître MVVM/détails comme celui-ci:WPF ComboBox en maître/détail MVVM

<Window.Resources> 
<DataTemplate DataType="{x:Type model:EveryDay}"> 
    <views:EveryDayView/> 
</DataTemplate> 

<DataTemplate DataType="{x:Type model:EveryMonth}"> 
    <views:EveryMonthView/> 
</DataTemplate> 
</Window.Resources> 

<Grid> 
    <ListBox Margin="12,24,0,35" Name="schedules" 
     IsSynchronizedWithCurrentItem="True" 
     ItemsSource="{Binding Path=Elements}" 
     SelectedItem="{Binding Path=CurrentElement}" 
     DisplayMemberPath="Name" HorizontalAlignment="Left" Width="120"/> 
    <ContentControl Margin="168,86,32,35" Name="contentControl1" 
     Content="{Binding Path=CurrentElement.Schedule}" /> 
    <ComboBox Height="23" Margin="188,24,51,0" Name="comboBox1" 
     VerticalAlignment="Top" 
      IsSynchronizedWithCurrentItem="True" 
      ItemsSource="{Binding Path=Schedules}" 
      SelectedItem="{Binding Path=CurrentElement.Schedule}" 
      DisplayMemberPath="Name" 
      SelectedValuePath="ID" 
      SelectedValue="{Binding Path=CurrentElement.Schedule.ID}"/> 
</Grid> 

Cette fenêtre a DataContext Classe:

public class MainViewModel : INotifyPropertyChanged { 
    public MainViewModel() { 
     elements.Add(new Element("first", new EveryDay("First EveryDay object"))); 
     elements.Add(new Element("second", new EveryMonth("Every Month object"))); 
     elements.Add(new Element("third", new EveryDay("Second EveryDay object"))); 

     schedules.Add(new EveryDay()); 
     schedules.Add(new EveryMonth()); 
    } 

    private ObservableCollection<ScheduleBase> _schedules = new 
     ObservableCollection<ScheduleBase>(); 
    public ObservableCollection<ScheduleBase> Schedules { 
     get { 
      return _schedules; 
     } 

     set { 
      schedules = value; 
      this.OnPropertyChanged("Schedules"); 
     } 
    } 

    private Element _currentElement = null; 
    public Element CurrentElement { 
     get { 
      return this._currentElement; 
     } 

     set { 
      this._currentElement = value; 
      this.OnPropertyChanged("CurrentElement"); 
     } 
    } 

    private ObservableCollection<Element> _elements = new 
     ObservableCollection<Element>(); 
    public ObservableCollection<Element> Elements { 
     get { 
      return _elements; 
     } 

     set { 
      elements = value; 
      this.OnPropertyChanged("Elements"); 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 
} 

L'une des Vues:

<UserControl x:Class="Views.EveryDayView" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
<Grid > 
    <GroupBox Header="Every Day Data" Name="groupBox1" VerticalAlignment="Top"> 
     <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
      <TextBox Name="textBox2" Text="{Binding Path=AnyDayData}" /> 
     </Grid> 
    </GroupBox> 
</Grid> 

Mon SelectedItem dans ComboBo x ne fonctionne pas correctement. Y a-t-il des erreurs visibles dans mon code?

+0

Pouvez-vous fournir plus de détails? Quel comportement voyez-vous avec SelectedItem? Est-ce qu'il n'est jamais mis à jour? Inconsistement? –

+0

J'ai besoin d'une propriété d'élément d'édition Planifier sélectionné dans ListBox par ComboBox et par la suite par UserControls. ListBox et ComboBox sont liés par CurrentElement dans ModelView. Pour sélectionner item - selectedItem de ComboBox, utilisez la fonction Equals() de Types EveryDay et EveryMonth. Cette fonction compare les pointeurs de Element.Schedule dans ListBox et Schedule dans ComboBox et bien sûr ils ne sont pas égaux. Comportement que j'attends de ComboBox que les objets d'une classe soient équivalents. Je peux vous envoyer du code. Merci Ben Von Handorf. – isak

Répondre

0

Ce que je fais habituellement lie les articles d'un ItemsControl à un ICollectionView (habituellement ListCollectionView) au lieu de directement à une collection; Je pense que c'est ce que le ItemsControl fait par défaut de toute façon (crée un ICollectionView par défaut), mais je peux me tromper.

Quoi qu'il en soit, ce qui vous permet de travailler avec la propriété CurrentItem du ICollectionView, qui est automatiquement synchronisé avec l'élément sélectionné dans un ItemsControl (si la propriété IsSynchronizedWithCurrentItem du contrôle est vrai ou null/default). Ensuite, lorsque vous avez besoin de l'élément actuel dans ViewModel, vous pouvez l'utiliser à la place. Vous pouvez également définir l'élément sélectionné en utilisant les méthodes MoveCurrentTo... sur ICollectionView. Mais en relisant la question, je me rends compte que vous pourriez avoir un autre problème en même temps. vous avez une collection d'éléments 'par défaut' et vous avez besoin d'un moyen de les faire correspondre à des instances spécifiques. Il serait cependant une mauvaise idée de surcharger les opérateurs d'égalité des objets pour les considérer toujours égaux s'ils sont du même type, car cela pourrait rendre l'autre code très confus. J'envisagerais d'extraire l'information de type dans une énumération, et mettrait une propriété en lecture seule sur chaque objet retournant l'une des valeurs enum. Vous pouvez ensuite lier les éléments à une collection des valeurs enum et l'élément sélectionné à la propriété enum de chaque objet. Faites-moi savoir si vous avez besoin d'un exemple, je peux avoir fait un gâchis de l'explication :)