.net - 在 WPF DataGrid 中绑定(bind) ComboBoxColumn 的 ItemsSource

标签 .net wpf binding wpfdatagrid datagridcomboboxcolumn

我有两个简单的 Model 类和一个 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 设置为 App.xaml.cs 中 MainWindow 的 DataContext:

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

如您所见,我将 DataGrid 的 ItemsSource 设置为 ViewModel 的 GridItems 集合。这部分有效,显示了名为“Jim”的单条网格线。

我还想将每行中 ComboBox 的 ItemsSource 设置为 ViewModel 的 CompanyItems 集合。这部分不起作用:组合框保持为空,并且在调试器输出窗口中我看到一条错误消息:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=CompanyItems; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=28633162); target property is 'ItemsSource' (type 'IEnumerable')

我相信 WPF 期望 CompanyItemsGridItem 的属性,但事实并非如此,这就是绑定(bind)失败的原因。

我已经尝试过使用 RelativeSourceAncestorType,如下所示:

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

但这在调试器输出中给了我另一个错误:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=CompanyItems; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=1150788); target property is 'ItemsSource' (type 'IEnumerable')

问题:如何将 DataGridComboBoxColumn 的 ItemsSource 绑定(bind)到 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 boxes with the WPF DataGrid

关于.net - 在 WPF DataGrid 中绑定(bind) ComboBoxColumn 的 ItemsSource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5409259/

相关文章:

wpf - 如何在silverlight中将子元素的宽度绑定(bind)到父元素的宽度

在 Apple 电脑上进行 .Net 编程

c# - 从非托管代码加载混合模式程序集

javascript - jquery 多重绑定(bind)

ios - Xamarin 统一 API - 如何使用 IntPtr 处理数组绑定(bind)?

WPF依赖属性问题

.net - 将字符串解析为整数(无论 hell 还是高水位)

c# - 如何读取WebClient的自定义 header 条目

c# - 如何在方法设置中为数组起订 It.IsAny?

c# - 如何在 try catch 语句中包装 MVVM Light ViewModel?