Mam model widoku do zarządzania widokiem typu okna dialogowego, który umożliwia filtrowanie wykazu (jeśli to konieczne) i wybór elementu. Kod działa poprawnie bez względu na to, czy ustawiłem IsSynchronizedWithCurrentItem na true, czy nie. Rozumiem, że ta właściwość nie jest domyślnie prawdą w ListView, więc chciałbym lepiej zrozumieć tę właściwość.Atrybut IsSynchronizedWithCurrentItem i aktualizacje bieżącego elementu
Oto konfiguracja wiążący w XAML widoku (który działa tak samo dobrze bez ustalania własności synch):
<ListView
ItemsSource="{Binding Projects.View}"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedProject, Mode=TwoWay}"
>
widoku modelu Projekty jest rzeczywiście CollectionViewSource który jest wspierany przez prywatnego ObservableCollection. Chyba wziąłem tę ideę z przykładowego projektu Josha Smitha, ale szczerze mówiąc nie pamiętam teraz. Oto odnośny fragment VM, który odnosi się do XAML wiązania:
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; }
Właściwość Filter z CollectionViewSource nie ma obsługi, która zwraca różne predykaty na pozycji widoku modelu w wykazie, który jest odbierany przez wiązaniami prawidłowo. Oto sedno tego kodu (który jest w tej samej 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;
}
Ustawianie trybu = TwoWay jest zbędny, ponieważ wiązanie SelectedItem ListView jest dwukierunkowy domyślnie, ale nie przeszkadza mi bycie wprost o (Mogę inaczej o tym myśleć po lepszym zrozumieniu WPF).
Co na temat mojego kodu sprawia, że IsSynchronizedWithCurrentItem = True redundantne?
Mam przeczucie, że to przyzwoity kod, ale nie podoba mi się, że jego części działają dzięki "magii", co oznacza, że z przyjemnością przyjmuję wszelkie konstruktywne opinie!
Cheers,
Berryl