Frage

Ich habe ein View-Modell einen Dialog Art der Ansicht zu verwalten, die Filterung eine Auflistung (falls erforderlich) und Auswahl eines Element erlaubt. Der Code funktioniert gut, ob ich IsSynchronizedWithCurrentItem auf true gesetzt ist oder nicht. Mein Verständnis ist, dass diese Eigenschaft standardmäßig in einem Listview nicht wahr ist, so möchte ich besser, diese Eigenschaft zu verstehen.

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 sind eigentlich ein Collection, die von einem privaten ObservableCollection unterstützt wird. Ich denke, dass ich diese Idee von einem Beispielprojekt von Josh Smith glommed, aber ich ehrlich gesagt nicht gerade jetzt wieder zu verwenden. Hier ist der relevante Teil der VM, die auf die 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 Filter-Eigenschaft des Collection hat einen Handler, die verschiedene Prädikate auf den View-Modell Elemente in der Liste gibt, die richtig von den Bindungen aufgenommen wird. 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;
    }

, um den Modus = TwoWay Einstellung ist überflüssig, da die Listenansicht der SelectedItem Bindung Zweiweg ist standardmäßig, aber ich habe nichts dagegen nicht explizit zu werden darüber (ich könnte das Gefühl, anders zu, wenn ich WPF besser zu verstehen).

Was ist mit meinem Code macht die IsSynchronizedWithCurrentItem = True überflüssig?

Mein Bauch ist, dass diese anständige Code ist, aber ich mag es nicht, dass Teile davon scheinen über „Magie“ zu arbeiten, was bedeutet, ich würde jedes konstruktives Feedback willkommen!

Cheers,
Berryl

War es hilfreich?

Lösung

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

Da Sie nie die CurrentItem des CollectionView verwenden, und Sie erscheinen nicht zweimal auf die gleiche Sammlung zu binden, um die betreffende Eigenschaft Einstellung hat keine sichtbaren Auswirkungen auf alle.


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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top