Dot-Net

在 WPF DataGrid 中綁定 ComboBoxColumn 的 ItemsSource

  • March 23, 2011

我有兩個簡單的模型類和一個 ViewModel …

public class GridItem
{
   public string Name { get; set; }
   public int CompanyID { 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 } };

       CompanyItems = new ObservableCollection<CompanyItem>() {
           new CompanyItem() { ID = 1, Name = "Company 1" },
           new CompanyItem() { ID = 2, Name = "Company 2" } };
   }

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

…和一個簡單的視窗:

<Window x:Class="DataGridComboBoxColumnApp.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="MainWindow" Height="350" Width="525">
   <Grid>
       <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding GridItems}" >
           <DataGrid.Columns>
               <DataGridTextColumn Binding="{Binding Name}" />
               <DataGridComboBoxColumn ItemsSource="{Binding CompanyItems}"
                                   DisplayMemberPath="Name"
                                   SelectedValuePath="ID"
                                   SelectedValueBinding="{Binding CompanyID}" />
           </DataGrid.Columns>
       </DataGrid>
   </Grid>
</Window>

ViewModel 設置為DataContextApp.xaml.cs 中的 MainWindow:

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

如您所見,我將ItemsSourceDataGrid設置GridItems為 ViewModel 的集合。這部分有效,顯示名稱為“Jim”的單個網格線。

我還想將ItemsSource每一行中的 ComboBox設置CompanyItems為 ViewModel 的集合。這部分不起作用:組合框保持為空,在調試器輸出視窗中我看到一條錯誤消息:

System.Windows.Data 錯誤:2:找不到目標元素的管理 FrameworkElement 或 FrameworkContentElement。BindingExpression:Path=CompanyItems; 數據項=空;目標元素是“DataGridComboBoxColumn”(HashCode=28633162);目標屬性是“ItemsSource”(類型“IEnumerable”)

我相信 WPF 期望CompanyItems成為一個GridItem不是這種情況的屬性,這就是綁定失敗的原因。

我已經嘗試過使用 aRelativeSourceAncestorType這樣的:

<DataGridComboBoxColumn ItemsSource="{Binding CompanyItems, 
   RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type Window}}}"
                       DisplayMemberPath="Name"
                       SelectedValuePath="ID"
                       SelectedValueBinding="{Binding CompanyID}" />

但這給了我調試器輸出中的另一個錯誤:

System.Windows.Data 錯誤:4:找不到與引用’RelativeSource FindAncestor,AncestorType =‘System.Windows.Window’,AncestorLevel =‘1’‘的綁定源。BindingExpression:Path=CompanyItems; 數據項=空;目標元素是“DataGridComboBoxColumn”(HashCode=1150788);目標屬性是“ItemsSource”(類型“IEnumerable”)

問題:如何將 DataGridComboBoxColumn 的 ItemsSource 綁定到 ViewModel 的 CompanyItems 集合?有可能嗎?

提前感謝您的幫助!

請檢查下面的 DataGridComboBoxColumn xaml 是否適合您:

<DataGridComboBoxColumn 
   SelectedValueBinding="{Binding CompanyID}" 
   DisplayMemberPath="Name" 
   SelectedValuePath="ID">

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

在這裡,您可以找到解決您面臨的問題的另一種解決方案:Using combo box with the WPF DataGrid

引用自:https://stackoverflow.com/questions/5409259