2009-11-30 3 views
9

J'ai un modèle de vue pour gérer un type de vue de type dialogue qui permet le filtrage d'une liste (si nécessaire) et la sélection d'un élément. Le code fonctionne correctement si j'ai défini IsSynchronizedWithCurrentItem sur true ou non. Ma compréhension est que cette propriété n'est pas vraie par défaut dans un ListView, donc je voudrais mieux comprendre cette propriété.Attribut IsSynchronizedWithCurrentItem et mises à jour de l'élément actuel

Voici la configuration de liaison dans le XAML de la vue (qui fonctionne aussi bien sans le paramètre de propriété synch):

<ListView 
      ItemsSource="{Binding Projects.View}" 
      IsSynchronizedWithCurrentItem="True" 
      SelectedItem="{Binding SelectedProject, Mode=TwoWay}"    
         > 

Le modèle vue Projets est en fait un CollectionViewSource qui est soutenu par un ObservableCollection privé. Je pense que j'ai trouvé cette idée à partir d'un exemple de projet de Josh Smith, mais je ne me souviens pas honnêtement en ce moment. Voici la partie pertinente de la machine virtuelle qui se rapporte à la xaml liaison:

private ObservableCollection<ProjectViewModel> _projectsInternal { get; set; } 
public CollectionViewSource Projects { get; set; } 

private void _populateProjectListings(IEnumerable<Project> openProjects) { 
    var listing = (from p in openProjects 
        orderby p.Code.ToString() 
        select new ProjectViewModel(p)).ToList(); 

    foreach (var pvm in listing) 
      pvm.PropertyChanged += _onProjectViewModelPropertyChanged; 

    _projectsInternal = new ObservableCollection<ProjectViewModel>(listing); 

    Projects = new CollectionViewSource {Source = _projectsInternal}; 
} 

/// <summary>Property that is updated via the binding to the view</summary> 
public ProjectViewModel SelectedProject { get; set; } 

la propriété de filtre du CollectionViewSource a un gestionnaire qui renvoie différents prédicats sur les éléments du modèle de vue dans la liste qui est capté par les liaisons correctement. Voici l'essentiel de ce code (qui est dans le même ProjectSelctionViewModel):

/// <summary>Trigger filtering of the <see cref="Projects"/> listing.</summary> 
    public void Filter(bool applyFilter) 
    { 
     if (applyFilter) 
      Projects.Filter += _onFilter; 
     else 
      Projects.Filter -= _onFilter; 

     OnPropertyChanged<ProjectSelectionViewModel>(vm=>vm.Status); 
    } 

    private void _onFilter(object sender, FilterEventArgs e) 
    { 
     var project = e.Item as ProjectViewModel; 
     if (project == null) return; 

     if (!project.IsMatch_Description(DescriptionText)) e.Accepted = false; 
     if (!project.IsMatch_SequenceNumber(SequenceNumberText)) e.Accepted = false; 
     if (!project.IsMatch_Prefix(PrefixText)) e.Accepted = false; 
     if (!project.IsMatch_Midfix(MidfixText)) e.Accepted = false; 
     if (!project.IsAvailable) e.Accepted = false; 
    } 

Réglage du mode = TwoWay est redondant puisque le SelectedItem de ListView de liaison est à double sens par défaut, mais je ne me dérange pas d'être explicite sur il (je pourrais avoir une opinion différente à ce sujet une fois que je comprendrais mieux WPF).

Qu'en est-il de mon code qui rend IsSynchronizedWithCurrentItem = True redondant? Mon instinct est que c'est un code décent, mais je n'aime pas que certains morceaux semblent fonctionner par "magie", ce qui signifie que je serais heureux de recevoir des commentaires constructifs!

Cheers,
Berryl

Répondre

13

IsSynchronizedWithCurrentItem permet de synchroniser le CurrentItem de la valeur par défaut CollectionView de la collection liée à la SelectedItem de votre commande.

Puisque vous n'utilisez jamais le CurrentItem du CollectionView et que vous ne semblez pas lier deux fois la même collection, la propriété en question n'a aucun effet visible.


Demo de la façon dont les synchronisations de propriété (pour les téléspectateurs XAML comme Kaxaml ou XAMLPad):

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Page.Resources> 
     <x:Array x:Key="Items" Type="{x:Type sys:String}"> 
      <sys:String>Apple</sys:String> 
      <sys:String>Orange</sys:String> 
      <sys:String>Pear</sys:String> 
      <sys:String>Lime</sys:String> 
     </x:Array> 
    </Page.Resources> 
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> 
     <StackPanel Background="Transparent"> 
      <ListBox IsSynchronizedWithCurrentItem="True" ItemsSource="{StaticResource Items}" /> 
      <ListBox IsSynchronizedWithCurrentItem="True" ItemsSource="{StaticResource Items}" /> 
      <!-- This TextBlock binds to the CurrentItem of the Items via the "/" --> 
      <TextBlock Text="{Binding Source={StaticResource Items}, Path=/}"/> 
     </StackPanel> 
    </ScrollViewer> 
</Page>