2017-07-31 91 views
0

綁定到CollectionView源時,所有行顯示最初顯示的空白值,然後當我更改任何組合框的選擇時,所有組合框都設置爲相同的值。當我直接綁定到ObservableCollection的源集合時,它可以正常工作。我想使用一個CollectionViewSource,這樣我就可以利用它的排序功能等。下面是一些代碼,它使用一個綁定到CollectionViewSource的列和一個直接綁定到底層ObservableCollection的方法來解決問題。我使用VS 2015將數據網格組合框列綁定到CollectionViewSource時的奇怪行爲

視圖模型:

public class GridItem 
{ 
    public string Name { get; set; } 
    public int CompanyID { get; set; } 
    public int CompanyID2 { get; set; } 
} 

public class CompanyItem 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
} 

public class ViewModel 
{ 
    public ViewModel() 
    { 
     GridItems = new ObservableCollection<GridItem>() { 
      new GridItem() { Name = "Jim", CompanyID = 1, CompanyID2 = 1 }, 
      new GridItem() { Name = "Ed", CompanyID = 2, CompanyID2 = 2 }, 
      new GridItem() { Name = "Dave", CompanyID = 3, CompanyID2 = 3 }, 
      new GridItem() { Name = "Bruce", CompanyID = 4, CompanyID2 = 4 }, 
      new GridItem() { Name = "Rob", CompanyID = 5, CompanyID2 = 5 } 
     }; 

     CompanyItems = new ObservableCollection<CompanyItem>() { 
      new CompanyItem() { ID = 1, Name = "Company 1" }, 
      new CompanyItem() { ID = 2, Name = "Company 2" }, 
      new CompanyItem() { ID = 3, Name = "Company 3" }, 
      new CompanyItem() { ID = 4, Name = "Company 4" }, 
      new CompanyItem() { ID = 5, Name = "Company 5" }, 
      new CompanyItem() { ID = 6, Name = "Company 6" }, 
      new CompanyItem() { ID = 7, Name = "Company 7" }, 
     }; 

     CompanyItemsViewSource = new CollectionViewSource(); 
     CompanyItemsViewSource.Source = CompanyItems; 
    } 

    public ObservableCollection<GridItem> GridItems { get; set; } 
    public ObservableCollection<CompanyItem> CompanyItems { get; set; } 
    public CollectionViewSource CompanyItemsViewSource { get; set; } 
} 

的窗口:

<Window x:Class="DataGridTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:DataGridTest" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" > 
      <DataGrid.Columns> 
       <DataGridTextColumn Binding="{Binding Name}" Header="Name"/> 

       <DataGridComboBoxColumn 
        SelectedValueBinding="{Binding CompanyID}" DisplayMemberPath="Name" SelectedValuePath="ID" Header="Company (View Source)"> 
        <DataGridComboBoxColumn.ElementStyle> 
         <Style TargetType="{x:Type ComboBox}"> 
          <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItemsViewSource.View, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
         </Style> 
        </DataGridComboBoxColumn.ElementStyle> 
        <DataGridComboBoxColumn.EditingElementStyle> 
         <Style TargetType="{x:Type ComboBox}"> 
          <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItemsViewSource.View, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
         </Style> 
        </DataGridComboBoxColumn.EditingElementStyle> 
       </DataGridComboBoxColumn> 

       <DataGridComboBoxColumn 
        SelectedValueBinding="{Binding CompanyID2}" DisplayMemberPath="Name" SelectedValuePath="ID" Header="Company"> 
        <DataGridComboBoxColumn.ElementStyle> 
         <Style TargetType="{x:Type ComboBox}"> 
          <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
         </Style> 
        </DataGridComboBoxColumn.ElementStyle> 
        <DataGridComboBoxColumn.EditingElementStyle> 
         <Style TargetType="{x:Type ComboBox}"> 
          <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
         </Style> 
        </DataGridComboBoxColumn.EditingElementStyle> 
       </DataGridComboBoxColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

數據上下文設置應用程序啓動時:

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     base.OnStartup(e); 

     MainWindow window = new MainWindow(); 
     ViewModel viewModel = new ViewModel(); 

     window.DataContext = viewModel; 
     window.Show(); 
    } 
} 
+0

你試過用'Collec tionViewSource'在XAML?例如'',然後在您的'DataGrid'中'。 – XAMlMAX

回答

1

要綁定同一個CollectionViewSource的所有不同行的相同視圖。當您更改其中一個行時,您正在操縱底層視圖,該視圖將在其他行上進行復制。

您需要針對不同的行具有不同的集合視圖。要僅使用一個屬性來執行此操作,每次調用get訪問器時都可以創建一個新視圖。

ICollectionView類型的新屬性添加到您的視圖模型是這樣的:

public ICollectionView CompanyItemCollectionView 
{ 
    get 
    {    
     return new CollectionViewSource { Source = CompanyItems }.View; 
    } 
} 

綁定這個屬性到您的DataGridComboBoxColumn的元素的ItemsSource:

<DataGridComboBoxColumn 
SelectedValueBinding="{Binding CompanyID}" DisplayMemberPath="Name" SelectedValuePath="ID" Header="Company (ICollectionView)"> 
    <DataGridComboBoxColumn.ElementStyle> 
     <Style TargetType="{x:Type ComboBox}"> 
      <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItemCollectionView, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
     </Style> 
    </DataGridComboBoxColumn.ElementStyle> 
    <DataGridComboBoxColumn.EditingElementStyle> 
     <Style TargetType="{x:Type ComboBox}"> 
      <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CompanyItemCollectionView, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
     </Style> 
    </DataGridComboBoxColumn.EditingElementStyle> 
</DataGridComboBoxColumn> 

您可以設置過濾器和排序訂購裏面的獲取訪問者太:

public ICollectionView CompanyItemCollectionView 
{ 
    get 
    { 
     ICollectionView view = new CollectionViewSource { Source = CompanyItems }.View; 
     view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Descending)); //example     
     return view; 
    } 
} 
+0

非常感謝。爲每一行創建視圖不是很沉重嗎? – Shane

+0

我對性能並不確定。我會說它會好的,這取決於你所擁有的行數。但是:https://blogs.msdn.microsoft.com/audiofool/2007/06/14/the-rules-of-code-optimization/試一試,看看它是否滿足您的需求。如果沒有,請搜索另一個解決方案。 –

相關問題