2009-11-30 27 views
9

我有一個視圖模型來管理對話框類型的視圖,允許篩選列表(如果需要)和項目的選擇。代碼工作正常,無論我設置IsSynchronizedWithCurrentItem爲true或不。我的理解是,這個屬性在默認情況下在ListView中不是真的,所以我想更好地理解這個屬性。IsSynchronizedWithCurrentItem屬性和當前項更新

這裏是在視圖的XAML綁定設置(其作品一樣好,而不同步屬性設置):

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

視圖模型項目實際上是由一個私人的ObservableCollection支持的CollectionViewSource。我想我從Josh Smith的一個樣本項目中找到了這個想法,但我現在實在不記得了。下面是涉及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的Filter屬性有一個處理程序,其上由所述綁定拾起在列表視圖模型項返回各個謂詞正確。下面是代碼的要點(這是在同一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綁定在默認情況下雙向的,但我不介意被明確有關它(當我更好地理解WPF時,我可能會有不同的感覺)。

我的代碼是什麼讓IsSynchronizedWithCurrentItem =真多餘?

我的直覺是,這是體面的代碼,但我不喜歡它通過「魔術」工作,這意味着我會歡迎任何建設性的反饋!

乾杯,
Berryl

回答

13

IsSynchronizedWithCurrentItem同步綁定集合的默認CollectionView您控制的SelectedItemCurrentItem

由於您從不使用CollectionViewCurrentItem,並且您似乎沒有綁定到相同的集合兩次,因此設置該屬性根本沒有可見的效果。的


演示如何屬性同步(XAML的觀衆喜歡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>