2009-11-30 37 views
9

Tôi có một kiểu xem để quản lý kiểu xem hộp thoại cho phép lọc danh sách (nếu cần) và chọn một mục. Mã hoạt động tốt cho dù tôi đặt IsSynchronizedWithCurrentItem thành true hay không. Sự hiểu biết của tôi là thuộc tính này không đúng theo mặc định trong một ListView, vì vậy tôi muốn hiểu rõ hơn về thuộc tính này.IsSynchronizedWithCurrentItem thuộc tính và cập nhật mục hiện tại

Đây là thiết lập ràng buộc trong XAML của view (trong đó hoạt động giống như cũng không cài đặt thuộc tính đồng bộ):

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

Quan điểm dự án mô hình thực sự là một CollectionViewSource được hỗ trợ bởi một ObservableCollection tin. Tôi nghĩ tôi đã đưa ra ý tưởng này từ một dự án mẫu của Josh Smith, nhưng tôi thành thật không nhớ lại ngay bây giờ. Dưới đây là phần có liên quan của VM có liên quan đến XAML ràng buộc:

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

Thuộc tính Bộ lọc của CollectionViewSource có một handler mà trả về vị khác nhau vào các mục xem mô hình trong danh sách được chọn bởi các ràng buộc đúng. Dưới đây là các ý chính của mã đó (đó là trong ProjectSelctionViewModel giống nhau):

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

Thiết Mode = TwoWay là không cần thiết vì ràng buộc SelectedItem của ListView là hai chiều theo mặc định, nhưng tôi không nhớ được rõ ràng về nó (tôi có thể cảm thấy khác nhau về điều đó một khi tôi hiểu WPF tốt hơn).

Điều gì về mã của tôi đang tạo IsSynchronizedWithCurrentItem = True dự phòng?

Đường ruột của tôi là đây là mã phong nha, nhưng tôi không thích những phần đó dường như hoạt động thông qua "ma thuật", có nghĩa là tôi sẽ chào đón bất kỳ phản hồi mang tính xây dựng nào!

Chúc mừng,
Berryl

Trả lời

13

IsSynchronizedWithCurrentItem đồng bộ các CurrentItem mặc định CollectionView của bộ sưu tập ràng buộc với SelectedItem tầm kiểm soát của bạn.

Vì bạn không bao giờ sử dụng CurrentItem của CollectionView và bạn dường như không ràng buộc với cùng một bộ sưu tập hai lần, hãy đặt thuộc tính được đề cập không có hiệu ứng rõ ràng.


Demo về cách đồng bộ tài sản (đối với người xem XAML như Kaxaml hoặc 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> 
Các vấn đề liên quan