Atributo IsSynchronizedWithCurrentItem e atualizações de itens atuais
Eu tenho um modelo de exibição para gerenciar um tipo de exibição de diálogo que permite a filtragem de uma listagem (se necessário) e a seleção de um item. O código funciona bem se eu definir IsSynchronizedWithCurrentItem como true ou não. Meu entendimento é que essa propriedade não é verdadeira por padrão em um ListView, então eu gostaria de entender melhor essa propriedade.
Aqui está a configuração de ligação no xaml da view (que funciona tão bem sem a configuração da propriedade synch):
<ListView
ItemsSource="{Binding Projects.View}"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedProject, Mode=TwoWay}"
>
O modelo de visualização Projetos é realmente um CollectionViewSource que é feito por um ObservableCollection privado. Eu acho que eu glommed esta idéia de um projeto de amostra de Josh Smith, mas eu sinceramente não me lembro agora. Aqui está a parte relevante da VM que se relaciona com a ligação 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; }
A propriedade Filter do CollectionViewSource possui um manipulador que retorna vários predicados nos itens do modelo de exibição na lista, que é selecionado corretamente pelas ligações. Aqui está a essência desse código (que está no mesmo 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;
}
Definir o Mode = TwoWay é redundante, já que a ligação SelectedItem do ListView é bidirecional por padrão, mas não me importo de ser explícito sobre isso (talvez eu sinta diferentemente sobre isso assim que entender melhor o WPF).
E o meu código está fazendo o IsSynchronizedWithCurrentItem = True redundante?
Meu instinto é que este é um código decente, mas eu não gosto que partes dele parecem estar funcionando via "mágica", o que significa que gostaria de receber qualquer feedback construtivo!
Felicidades,
Berryl