Question

Je dispose d’un modèle de vue pour gérer un type de vue de dialogue qui permet de filtrer une liste (si nécessaire) et de sélectionner un élément. Le code fonctionne correctement, que je mette IsSynchronizedWithCurrentItem sur true ou non. D'après ce que j'ai compris, cette propriété n'est pas vraie par défaut dans un ListView. J'aimerais donc mieux comprendre cette propriété.

Voici la configuration de la 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 de vue Projects est en réalité un CollectionViewSource qui est sauvegardé par un ObservableCollection privé. Je pense que j'ai eu cette idée d'un exemple de projet de Josh Smith, mais honnêtement, je ne m'en souviens pas maintenant. Voici la partie pertinente de la machine virtuelle qui concerne la liaison xaml:

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é Filter de CollectionViewSource a un gestionnaire qui renvoie divers prédicats sur les éléments de modèle de vue de la liste, lesquels sont correctement pris en compte par les liaisons. Voici l'essentiel de ce code (qui se trouve 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;
    }

La définition du mode = TwoWay est redondante car la liaison SelectedItem de ListView est bidirectionnelle par défaut, mais cela ne me dérange pas d'être explicite à ce sujet (je pourrais me sentir différent de cela une fois que je comprendrai mieux WPF).

Pourquoi mon code rend-il IsSynchronizedWithCurrentItem = True redondant?

Mon instinct est que c'est un code correct, mais je n'aime pas que certaines de ses parties semblent fonctionner via "magique", ce qui signifie que je serais heureux de recevoir des commentaires constructifs!

À la vôtre,
Berryl

Était-ce utile?

La solution

IsSynchronizedWithCurrentItem synchronise le . CurrentItem de la valeur par défaut CollectionView de la collection liée avec le SelectedItem de votre contrôle.

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

Démonstration de la synchronisation de la propriété (pour les visualiseurs XAML tels que 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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top