2009-11-30 5 views
9

Ich habe ein Ansichtsmodell, um einen Dialogtyp der Ansicht zu verwalten, der das Filtern einer Auflistung (falls erforderlich) und die Auswahl eines Elements ermöglicht. Der Code funktioniert problemlos, wenn ich IsSynchronizedWithCurrentItem auf "true" festlege oder nicht. Nach meinem Verständnis ist diese Eigenschaft in einer ListView standardmäßig nicht richtig, daher möchte ich diese Eigenschaft besser verstehen.IsSynchronizedWithCurrentItem Attribut und aktuelle Artikelaktualisierungen

Hier ist die Bindung Setup in XAML Ansicht (die genauso gut ohne die Synch-Eigenschaftseinstellung funktioniert):

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

Die View-Modell-Projekte ist eigentlich ein Collection, die von einem privaten ObservableCollection unterstützt wird. Ich denke, ich habe diese Idee von einem Beispielprojekt von Josh Smith übernommen, aber ich kann mich ehrlich gesagt nicht erinnern. Hier ist der relevante Teil der VM, die mit dem XAML bezieht Bindung:

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; } 

die Filtereigenschaft der Collection einen Handler hat die verschiedene Prädikate auf dem Ansichtsmodell Elemente in der Liste gibt, die von den Bindungen aufgenommen wird korrekt. Hier ist der Kern dieses Codes (die in dem gleichen ProjectSelctionViewModel ist):

/// <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; 
    } 

die Modus-Einstellung = TwoWay ist überflüssig, da die Listview der SelectedItem Bindung Zweiweg standardmäßig, aber ich habe nichts dagegen zu sein Formulieren es (ich könnte mich anders darüber fühlen, sobald ich WPF besser verstehe).

Was ist mit meinem Code macht die IsSynchronizedWithCurrentItem = True redundant?

Mein Einfall ist, dass dies anständiger Code ist, aber ich mag es nicht, dass Teile davon über "Magie" funktionieren, was bedeutet, dass ich jede konstruktive Rückmeldung begrüßen würde!

Cheers,
Berryl

Antwort

13

IsSynchronizedWithCurrentItem syncs die CurrentItem des Standard CollectionView der gebundenen Sammlung mit dem SelectedItem Ihrer Kontrolle.

Da Sie nie die CurrentItem der CollectionView verwenden und Sie nicht scheinen, um an die gleiche Sammlung zweimal zu binden Einstellung der Eigenschaft in Frage hat keinen sichtbaren Effekt überhaupt.


Demo, wie die Eigenschaft Synchronisationen (für XAML Zuschauer wie Kaxaml oder 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> 
Verwandte Themen