2011-08-16 37 views
1

は知ってはいけない:WPF理解Selector.IsSynchronizedWithCurrentItem

インフラジスティックスxamDataGridのは、彼らのマニュアルに従って、データソースの現在の項目とのActiveRecordを同期するプロパティIsSynchronizedWithCurrentItemを公開しますICollectionViewを実装しています。

私がグリッドにバインドされたオブジェクトの種類に基づいて詳細(ContentControlに)コンテンツでは、次のMasterDetailsウィンドウがありますの背後にあるコードで

<DockPanel Name="dockPanel" LastChildFill="True"> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition/> 
       <RowDefinition Height="5" MaxHeight="5"/> 
       <RowDefinition/> 
      </Grid.RowDefinitions> 
      <igDP:XamDataGrid 
       Name="dataGrid"         
       IsSynchronizedWithCurrentItem="True" 
       SelectedItemsChanged="dataGrid_SelectedItemsChanged">      
      </igDP:XamDataGrid> 
      <GridSplitter    
       Style="{StaticResource blueHrizontalGridSplitter}" 
       Grid.Row="1" Grid.ColumnSpan="2"    
       BorderThickness="1" Margin="1,0" 
       HorizontalAlignment="Stretch" />    

      <ContentControl Grid.Row="2" Name="contentControl" /> 

     </Grid> 
    </DockPanel> 

を、私は、現在の項目の間のリンクを確立しようとしています次のような詳細のDataContextのにグリッドのデータソースは、私のMasterDetailsWindowのコンストラクタで制御します

if (detailsControl != null) 
      { 
       var fwDControl = detailsControl as FrameworkElement; 
       if (fwDControl != null) 
       { 
        var b = new Binding() { ElementName = "dataGrid", Path = new PropertyPath("DataSource") }; 
        fwDControl.SetBinding(DataContextProperty, b); 
       } 

       contentControl.Content = detailsControl;      
      } 
      else 
      { 
       var b = new Binding() { ElementName = "dataGrid", Path = new PropertyPath("DataSource") }; 
       contentControl.SetBinding(ContentProperty, b); 

       b = new Binding("DataDetailsTemplate"); 
       contentControl.SetBinding(ContentTemplateProperty, b); 
      } 

のMas​​terDetailsのインスタンスを構築し、呼び出し側がdetailsControlオブジェクトまたは文字列repreのいずれかを提供する必要がありますURLをDataTemplateに送信します。 detailsControlが提供されている場合は、詳細がnullでないかどうかをチェックするコードを実行します。それ以外の場合は、代わりにDataDetailsTemplateが提供されていると仮定します。

私は、次のDataTemplateに解決URLで、のMasterDetailsウィンドウのインスタンスを作成する場合、私はここに私の考えを疑ったがいるだろう :

<DataTemplate x:Key="LogDetailsTemplate">     
     <Grid Margin="5,5,5,0"> 
      <TextBox Text="{Binding Message}" TextWrapping="WrapWithOverflow"/>    
     </Grid>  
    </DataTemplate> 

グリッド内の項目を選択するには、選択したオブジェクトの表示しますTextBoxの対応するMessageプロパティ。

ただし、UserControlから派生したカスタムdetailsControlオブジェクトを提供し、グリッド内のアイテムを選択しても、detailsControlのDataContextは変更されません。どうしてこれなの?

TIA。

+0

私はこれがどのようにcurrentitem同期にも接続されているとは思わない... –

+0

dataGrid.DataSourceは明示的に自分のコレクションをラップするICollectionViewに設定されています。 dataGrid.IsSynchronizedWithCurrentItemもtrueに設定されているため、DataSource.CurrentItemへのバインディングパスを変更すると結果が変わらないため、DataSourceへのバインディングをICollectionView.CurrentItemにバインドすると思います。これは私が把握しようとしているものです:) –

+0

あなたは、複数の場所でコレクションを使用していないし、いずれかの現実的な物を使用していない、本当に任意の違いがない場合は、プロパティをtrueに設定します。 –

答えて

4

Whoa there !!!!!私は間違っているかもしれませんが、あなたはWinFormsの背景から来ているように見え、WinFormsのやり方と同じようにWPFで作業をしようとしています。

良い知らせは、次のようなことです。マスターディテールは、単純なフォワードスラッシュで処理できます。下の例では、MainWindow.xamlのバインディングを見ています。 - forwardslashは、現在選択されている項目を示しています。

MODELS

public class Country 
{ 
    public string Name { get; set; } 
    public int Population { get; set; } 
} 

public class Continent 
{ 
    public string Name { get; set; } 
    public int Area { get; set; } 
    public IList<Country> Countries { get; set; } 
} 

のviewmodels

public class MainViewModel 
    { 
     private ObservableCollection<ContinentViewModel> _continents; 

     public ObservableCollection<ContinentViewModel> Continents 
     { 
      get { return _continents; } 
      set 
      { 
      _continents = value; 
      ContinentView = new ListCollectionView(_continents); 
      ContinentView.CurrentChanged += (sender, agrs) => CurrentContinent = ContinentView.CurrentItem as ContinentViewModel; 
     } 
    } 
    public ListCollectionView ContinentView {get; private set;} 

    /// <summary> 
    /// Use this to determine the current item in the list 
    /// if not willing to use \ notation in the binding. 
    /// </summary> 
    public ContinentViewModel CurrentContinent { get; set; } 
} 

public class ContinentViewModel 
{ 
    private Continent _model; 

    public Continent Model 
    { 
     get { return _model; } 
     set 
     { 
      _model = value; 
      Countries = _model.Countries 
       .Select(p => new CountryViewModel { Model = p }) 
       .ToList(); 
     } 
    } 

    public string Name 
    { 
     get { return Model.Name; } 
    } 

    public int Area 
    { 
     get { return Model.Area; } 
    } 

    public List<CountryViewModel> Countries { get; private set; } 
} 

public class CountryViewModel 
{ 
    public Country Model { get; set; } 

    public string Name 
    { 
     get { return Model.Name; } 
    } 

    public int Population 
    { 
     get { return Model.Population; } 
    } 
} 

MainWindow.xaml

<Window x:Class="XamDataGridMasterDetail.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:Views="clr-namespace:XamDataGridMasterDetail.Views" 
     xmlns:igDP="http://infragistics.com/DataPresenter" 
     Title="MainWindow"> 
    <Grid> 
     <StackPanel Orientation="Vertical"> 

      <!-- Continent list --> 
      <igDP:XamDataGrid HorizontalAlignment="Left" 
           Margin="10,10,0,0" 
           Name="xamDataGrid1" 
           Height="300" 
           VerticalAlignment="Top" 
           DataSource="{Binding ContinentView}" 
           IsSynchronizedWithCurrentItem="True"> 
       <igDP:XamDataGrid.FieldSettings> 
        <igDP:FieldSettings CellClickAction="SelectRecord" /> 
       </igDP:XamDataGrid.FieldSettings> 
       <igDP:XamDataGrid.FieldLayouts> 
        <igDP:FieldLayout> 
         <igDP:FieldLayout.Settings> 
          <igDP:FieldLayoutSettings AutoGenerateFields="False" /> 
         </igDP:FieldLayout.Settings> 
         <igDP:FieldLayout.Fields> 
          <igDP:Field Name="Name" 
             Label="Name" /> 
          <igDP:Field Name="Area" 
             Label="Area" /> 
          <igDP:UnboundField Label="# Countries" 
               Binding="{Binding Countries.Count}" /> 
         </igDP:FieldLayout.Fields> 
        </igDP:FieldLayout> 
       </igDP:XamDataGrid.FieldLayouts> 
      </igDP:XamDataGrid> 

      <!-- Continent detail --> 
      <ListBox ItemsSource="{Binding ContinentView/Countries}" 
        DisplayMemberPath="Name" 
        IsSynchronizedWithCurrentItem="True" 
        Height="200" /> 

      <!-- Country detail --> 
      <StackPanel Orientation="Horizontal"> 
       <Label Content="Name: " /> 
       <TextBlock Text="{Binding ContinentView/Countries/Name}" /> 
       <Label Content="Population: " /> 
       <TextBlock Text="{Binding ContinentView/Countries/Population}" /> 
      </StackPanel> 



     </StackPanel> 
    </Grid> 
</Window> 

App.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Data; 
using System.Linq; 
using System.Windows; 
using XamDataGridMasterDetail.ViewModels; 
using System.Collections.ObjectModel; 
using XamDataGridMasterDetail.Model; 

namespace XamDataGridMasterDetail 
{ 
    /// <summary> 
    /// Interaction logic for App.xaml 
    /// </summary> 
    public partial class App : Application 
    { 
     protected override void OnSessionEnding(SessionEndingCancelEventArgs e) 
     { 
      base.OnSessionEnding(e); 
     } 

     protected override void OnStartup(StartupEventArgs e) 
     { 
      base.OnStartup(e); 

      var view = new MainWindow(); 
      var vm = new MainViewModel(); 
      vm.Continents = new ObservableCollection<ContinentViewModel>(); 
      vm.Continents.Add(new ContinentViewModel 
      { 
       Model = new Continent 
       { 
        Name = "Australasia", 
        Area = 100000, 
        Countries = new[] 
        { 
         new Country 
         { 
          Name="Australia", 
          Population=100 
         }, 
         new Country 
         { 
          Name="New Zealand", 
          Population=200 
         } 
        } 
       } 
      }); 
      vm.Continents.Add(new ContinentViewModel 
      { 
       Model = new Continent 
       { 
        Name = "Europe", 
        Area = 1000000, 
        Countries = new[] 
        { 
         new Country 
         { 
          Name="UK", 
          Population=70000000 
         }, 
         new Country 
         { 
          Name="France", 
          Population=50000000 
         }, 
         new Country 
         { 
          Name="Germany", 
          Population=75000000 
         } 
        } 
       } 
      }); 
      view.DataContext = vm; 
      view.Show(); 
     } 

    } 
}