2009-11-30 1 views
9

リストのフィルタリング(必要な場合)と項目の選択を可能にするダイアログタイプのビューを管理するビューモデルがあります。 IsSynchronizedWithCurrentItemをtrueに設定するかどうかに関わらず、コードは正常に機能します。私の理解は、このプロパティはListViewのデフォルトでは真ではないので、このプロパティをよりよく理解したいと思います。ここでIsSynchronizedWithCurrentItem属性と現在のアイテムの更新

(同期プロパティの設定なしで同じようにうまく動作します)ビューのXAMLでバインディングの設定です:

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

ビューモデルプロジェクト、実際に民間のObservableCollectionに裏打ちされたCollectionViewSourceです。私はジョシュ・スミスのサンプルプロジェクトからこのアイデアを迎えたと思うが、正直言って、今は思い出していない。

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のフィルタプロパティは、バインディングによってピックアップされたリスト内のビューモデルアイテムに様々な述語を返すハンドラを有する:ここで結合XAMLに関するVMの関連部分であります正しくここでは(同じ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 = Trueを冗長にしていますか?

これはまともなコードですが、その部分は「魔法」によって動作しているようには思えません。これは建設的なフィードバックを歓迎することを意味します。

乾杯、
Berryl

答えて

13

IsSynchronizedWithCurrentItemは、あなたのコントロールのSelectedItemにバインドされたコレクションのデフォルトCollectionViewCurrentItemを同期します。

CollectionViewCurrentItemを使用することはなく、同じコレクションに2回バインドしないように見えるため、問題のプロパティを設定しても効果は全くありません。 (KaxamlまたはXAMLPadのようなXAMLの視聴者のために)どのようにプロパティ同期の


デモ:

<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> 
関連する問題