문제

목록 (필요한 경우) 및 항목 선택을 필터링 할 수있는 대화 상자 유형의보기를 관리하는 뷰 모델이 있습니다. 이 코드는 istynchronizedwithCurrentEM을 TRUE로 설정하든 제대로 작동합니다. 내 이해는이 속성이 ListView에서 기본적으로 사실이 아니기 때문에이 속성을 더 잘 이해하고 싶습니다.

다음은 View의 XAML의 바인딩 설정입니다 (Synch 속성 설정 없이도 작동).

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

View 모델 프로젝트는 실제로 개인 관측형 수집으로 뒷받침되는 CollectionViewSource입니다. 나는 Josh Smith 's의 샘플 프로젝트 에서이 아이디어를 발표했다고 생각하지만 지금은 솔직히 기억하지 못합니다. 다음은 XAML 바인딩과 관련된 VM의 관련 부분입니다.

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

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

ListView의 SelectedItem 바인딩이 기본적으로 두 가지 방법이므로 모드 설정 = twoway는 중복됩니다. 그러나 그것에 대해 명시 적으로 생각하지 않습니다 (WPF를 더 잘 이해하면 그것에 대해 다르게 느낄 수 있습니다).

내 코드는 어떨까요?

내 직감은 이것이 괜찮은 코드라는 것이지만, 나는 그것이 "Magic"을 통해 작동하는 것 같지 않습니다. 즉, 건설적인 피드백을 환영합니다!

건배,
베리

도움이 되었습니까?

해결책

IsSynchronizedWithCurrentItem 동기화 CurrentItem 기본값의 CollectionView The와의 바운드 컬렉션의 SelectedItem 당신의 통제의.

당신은 결코 사용하지 않기 때문에 CurrentItemCollectionView 그리고 당신은 동일한 컬렉션에 두 번 묶는 것처럼 보이지 않습니다. 문제의 속성은 전혀 눈에 띄는 효과가 없습니다.


속성이 동기화되는 방법의 데모 (XAML Viewers의 경우 Kaxaml 또는 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>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top