WPF DataGridComboBoxColumn不起作用 [英] WPF DataGridComboBoxColumn not working

查看:391
本文介绍了WPF DataGridComboBoxColumn不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在WPF项目集的DataGrid中有一个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:

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

并且集合viewmodel具有这些属性

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

我仅出于测试目的显示Id,将来会添加一个description属性.

为什么ComboBoxColumn不起作用?

解决方案

您的问题是由DataGridColumns引起的:实际上,它们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是资源的名称.

希望它能为您提供帮助.

编辑

我使用从

然后在XAML中,您需要添加:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

I have a DataGridComboBoxColumn in a DataGrid in a WPF project set like this:

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

but when I run the project the column display only blank values and the combobox in edit mode does the same thing.

The DataGrid is set like this:

<DataGrid Name="ReadersGrid"  Grid.Row="0" Grid.Column="0" Margin="3" ItemsSource="{Binding Readers}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False">

And the UserControl like this:

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

and the other columns, only text, work fine.

The ViewModel has these properties

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

And the collection viewmodel has these properties

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

I'm displaying Id only for test, a description property will be added in future.

Why the ComboBoxColumn is not working?

解决方案

Your issue is caused by DataGridColumns: indeed they do not belong to the visual tree, so you cannot bind their properties to your DataContext.

You can find here a solution based on a kind of freezable "DataContext proxy", since Freezable objects can inherit the DataContext even when they are not in the visual tree.

Now if you put this proxy in the DataGrid's resources, it can be bound the the DataGrid's DataContext and can be retrieve by using the StaticResource keyword.

So you XAML will become:

<DataGridComboBoxColumn Header="Master" SelectedItemBinding="{Binding MasterId}"
    SelectedValueBinding="{Binding Id}" DisplayMemberPath="Id"
    ItemsSource="{Binding Data.Masters, Source={StaticResource proxy}}" />

Where proxy is the name of your resource.

I hope it can help you.

EDIT

I update my answer with the code copied from this link (because of @icebat's comment). This is the BindingProxy class:

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

Then in the XAML you need to add:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

这篇关于WPF DataGridComboBoxColumn不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆