У меня есть модель представления для управления типом диалога, который позволяет фильтровать список (при необходимости) и выбирать элемент. Код работает нормально, независимо от того, установил ли я IsSynchronizedWithCurrentItem в true или нет. Насколько я понимаю, это свойство не является истинным по умолчанию в ListView, поэтому я хотел бы лучше понять это свойство.
Вот настройка привязки в представлении xaml (которое работает так же хорошо без установки свойства синхронизации):
<ListView
ItemsSource="{Binding Projects.View}"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedProject, Mode=TwoWay}"
>
Модель представления Projects на самом деле представляет собой CollectionViewSource, который поддерживается частной ObservableCollection. Я думаю, что я воплотил эту идею в пример проекта Джоша Смита, но, честно говоря, сейчас не вспоминаю. Вот соответствующая часть виртуальной машины, которая относится к привязке 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; }
Свойство Filter в CollectionViewSource имеет обработчик, который возвращает различные предикаты для элементов модели представления в списке, которые правильно подобраны привязками. Вот суть этого кода (который находится в том же 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;
}
Установка режима = TwoWay является избыточным, поскольку привязка SeViewItem в ListView по умолчанию является двухсторонней, но я не возражаю быть откровенным по этому поводу (я могу почувствовать себя по-другому, когда лучше пойму WPF).
Что в моем коде делает IsSynchronizedWithCurrentItem = True избыточным?
Меня интересует, что это приличный код, но мне не нравится, что его части, кажется, работают через "магию", а это значит, что я приветствую любые конструктивные отзывы!
Приветствия
Berryl