WPF数据网格组合框列无法正常工作。

4

我在一个 WPF 项目中有一个 DataGridComboBoxColumn,设置如下:

<DataGridComboBoxColumn Header="Master" SelectedItemBinding="{Binding MasterId}" SelectedValueBinding="{Binding Id}" DisplayMemberPath="Id" ItemsSource="{Binding Masters}" />

但是当我运行项目时,列只显示空白值,并且编辑模式下的组合框也是同样的情况。
DataGrid 的设置如下:
<DataGrid Name="ReadersGrid"  Grid.Row="0" Grid.Column="0" Margin="3" ItemsSource="{Binding Readers}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False">

以下是类似于此的用户控件:

<UserControl x:Class="SmartAccess.Tabs.ReadersTab"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:SmartAccess.Tabs"
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" DataContext="{StaticResource ReadersListViewModel}">

而其他列,只有文本,可以正常工作。

ViewModel具有以下属性

public ObservableCollection<ReaderViewModel> Readers { get; set; }
public IEnumerable<ReaderViewModel> Masters => Readers.Concat(new List<ReaderViewModel> { new ReaderViewModel { Id = -1 } }).OrderBy(t => t.Id);

集合视图模型具有以下属性

public long Id { get; set; }
public long MasterId { get; set; }

我只是为了测试而显示 Id,未来会添加描述属性。

为什么 ComboBoxColumn 没有工作?


我没有看到问题。建议您阅读http://stackoverflow.com/help/mcve,以获取有关如何提出此类问题的建议。欢迎来到Stack Overflow! - Philip Pittle
可能存在绑定问题,请查看运行项目的输出窗口,它应该会告诉您找不到哪些属性以及它在哪里寻找它们。 - omerts
@omerts,错误信息如下:System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Masters; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=24534150); target property is 'ItemsSource' (type 'IEnumerable'),但我不理解。 - Matteo Bruni
Masters 不是 ReaderViewModel 的属性,而它是单元格的 DataContext。你需要使用列的 ItemsSource 的相对源绑定。 - icebat
@icebat 谢谢,但我不明白如何从VM中获取“Masters”属性。我尝试了这个,但它不起作用:<DataGridComboBoxColumn Header="Master" SelectedItemBinding="{Binding MasterId}" SelectedValueBinding="{Binding Id}" DisplayMemberPath="Id" ItemsSource="{Binding DataContext.Masters, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:ReadersTab}}}" /> - Matteo Bruni
1个回答

7
您的问题是由于DataGridColumns造成的:它们确实不属于可视树, 因此您无法将它们的属性绑定到您的DataContext上。
您可以在这里找到一种基于一种冻结的“DataContext代理”的解决方案,因为Freezable对象即使不在可视树中也可以继承DataContext
现在,如果您将此代理放入DataGrid的资源中,它就可以被绑定到DataGridDataContext,并且可以通过使用StaticResource关键字检索。
因此,您的XAML将变为:
<DataGridComboBoxColumn Header="Master" SelectedItemBinding="{Binding MasterId}"
    SelectedValueBinding="{Binding Id}" DisplayMemberPath="Id"
    ItemsSource="{Binding Data.Masters, Source={StaticResource proxy}}" />

其中 proxy 是您资源的名称。

希望这可以帮助您。

编辑

我更新了我的答案,其中包括从 link 复制的代码(因为 @icebat 的评论)。这是 BindingProxy 类:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

然后在XAML中需要添加:
<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

我并不完全理解这个例子,但它似乎按预期工作。谢谢。 - Matteo Bruni
@IlVic,太棒了! - icebat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接