WPF使用DataGridComboBoxColumn完成绑定

 在使用DataGrid的时候,有时候需要使某些列为ComboBox,这时自然想到使用DataGridComboBoxColumn,但是如果使用的是ItemsSource数据绑定后台的对象,就会发现,这根本就不能用。

  首先,看有问题的代码:

后台代码:

using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace WPFTest
{
    /// <summary>
    /// 数据项
    /// </summary>
    public class DataItem
    {
        public int Value { get; set; }
        public DataItem(int val) { Value = val; }
    }
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // 选中数据
            SelectedList.Add(new DataItem(1)); SelectedList.Add(new DataItem(2));
            // 可选数据
            SelectionList.Add(1); SelectionList.Add(2); SelectionList.Add(3);
        }

        /// <summary>
        /// 选中的数据列表
        /// </summary>
        public ObservableCollection<DataItem> SelectedList
        {
            get { return _selectedList; }
            set { _selectedList = value; }
        }
        private ObservableCollection<DataItem> _selectedList = new ObservableCollection<DataItem>();

        /// <summary>
        /// 可供选择的数据列表
        /// </summary>
        public ObservableCollection<int> SelectionList
        {
            get { return _selectionList; }
            set { _selectionList = value; }
        }
        private ObservableCollection<int> _selectionList = new ObservableCollection<int>();

        // 显示选中的
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TBX_Selected.Text = "";
            foreach (var item in SelectedList)
                TBX_Selected.Text += item.Value.ToString(" --->0<--- ");
        }

    }
}

前台为:

<Window x:Class="WPFTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WPFTest" Name="this" Height="350" Width="525">
    <StackPanel>
        <DataGrid ItemsSource="{Binding Path=SelectedList,ElementName=this}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="文本模式" Binding="{Binding Path=Value}" />
                <DataGridComboBoxColumn Header="ComboBox模式"
                                        SelectedValueBinding="{Binding Path=Value}"
                                        ItemsSource="{Binding Path=SelectionList,ElementName=this}" />
            </DataGrid.Columns>
        </DataGrid>
        <Button Content="观察选中的数据" Click="Button_Click" Margin="10"/>
        <TextBox Name="TBX_Selected" />
    </StackPanel>
</Window>

  在这里通过把Window控件的Name设置为this,然后在绑定的时候指定ElementName=this及Path属性来关联到后台数据源。为了测试是否有效,我还定义了一个TextBox来显示SelectedList中的数据的值。首先,可以肯定的是,用DataGridTextColumn一点问题也没有,数据可以正常地显示和更新,但是使用DataGridComboBoxColumn时问题就出现了,数据不能显示,就像什么都没有绑定上去一样:

  我在网上找了下资料,都与MSDN上的例子相似,DataGridComboBoxColumn对数据源有下面的要求:

使用下列选项之一,若要填充下拉列表,首先设置 ComboBox 的 ItemsSource 属性:

  于是,试试DataGridTemplateColumn来做ComboBox:  

 <DataGridTemplateColumn Header="Template模式">
     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
             <ComboBox SelectedValue="{Binding Path=Value}" ItemsSource="{Binding Path=SelectionList,ElementName=this}" />
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
 </DataGridTemplateColumn>

  运行发现,显示是正常了,但是不论我怎么改,SelectedList中的数据都不带改变,我尝试设置了ComboBox的各项属性,也没有成功。但是非常奇怪的地方是,如果在选择后,去点了上面的DataGridComboBoxColumn ,数据就能正常正同步过去:

  我想这可能是DataGridComboBoxColumn在选择后会触发一个事件,完成同步工作。

  好了,这样还是不行,我去了stackoverflow上找资料,问题终于得到了解决。基本上原因是这样的:DataGrid的列并没有数据上下文,所以DataGridTemplateColumn中的ComoBox从未添加到“Visual Tree(可视化树)”中。只要Grid绘制了单元,并且得到了数据上下文后,就能正常地使用ItemsSource属性来完成绑定了。修正后的代码:

 <DataGridComboBoxColumn Header="ComboBox模式(修正)">
     <DataGridComboBoxColumn.EditingElementStyle>
         <Style TargetType="ComboBox">
             <Setter Property="ItemsSource" Value="{Binding Path=SelectionList,ElementName=this}" />
             <Setter Property="SelectedValue" Value="{Binding Path=Value}" />
         </Style>
     </DataGridComboBoxColumn.EditingElementStyle>
 </DataGridComboBoxColumn>

  这样,数据能够正常地同步了,但是如果不点中对应单元格,ComboBox就不会显示出来,只有点中了才显示,继续参考资料,问题原因是上面只设置了EditingElementStyle(编辑时样式),所以在选中编辑时就会出现ComboBox,要想一直显示,还得设置ElementStyle,使它和EditingElementStyle一样就行了:

<DataGridComboBoxColumn.ElementStyle>
    <Style TargetType="ComboBox">
        <Setter Property="ItemsSource" Value="{Binding Path=SelectionList,ElementName=this}" />
        <Setter Property="SelectedValue" Value="{Binding Path=Value}" />
    </Style>
</DataGridComboBoxColumn.ElementStyle>

  

  问题圆满解决,其实也不难,只是不知道,没想到而已,大家可以看看。

  转载请注明原址:http://www.cnblogs.com/lekko/archive/2012/11/23/2784789.html

时间: 2024-10-16 11:57:11

WPF使用DataGridComboBoxColumn完成绑定的相关文章

WPF 在事件中绑定命令(可以在模版中绑定命令)

其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是如何构建使用的还不够,很多情况下我们都需要在某个事件触发的时候才去触发命令,所以将命令绑定到事件上是非常有效的做法,下面我们来接着实现将命令绑定到事件中. WPF实现命令绑定到事件 使用 System.Windows.Interactivity.dll 中的 Interaction 可以帮助我们实现

WPF 在事件中绑定命令

导航:MVVMLight系列文章目录:<关于 MVVMLight 设计模式系列> 其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是如何构建使用的还不够,很多情况下我们都需要在某个事件触发的时候才去触发命令,所以将命令绑定到事件上是非常有效的做法,下面我们来接着实现将命令绑定到事件中. WPF实现命令绑定到事件 使用 System.Windows

WPF窗体视图中绑定Resources文件中字符串时,抛出:System.Windows.Markup.StaticExtension

问题描述: 在Resources.resx定义了一个静态字符串字段Title,并在WPF窗体视图中绑定为窗体的标题: Title="{x:Static local:Resources.Title}" 但是,在运行应用时,抛出System.Windows.Markup.StaticExtension异常. 原因: 解决方案: 将Resources.resx的访问修饰符由internal修改为public.

实战基础技能(08)--------MVVM模式中WPF数据的完全绑定

一:截图,描述:将后台代码的姓名.年龄绑定到文本框,单击”增加年龄“--年龄自+1,单击”显示年龄“--弹出年龄的显示对话框,实现了从文本框修改年龄和后台更改年龄并显示到文本框 运行结果和解决方案管理截图如下: 二:person类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace 完全数据绑定 {

WPF(6):概念绑定

WPF 的体系结构,标记扩展,依赖属性,逻辑树/可视化树,布局,转换等.今天,我们将讨论 WPF 最重要的一部分——绑定.WPF 带来了优秀的数据绑定方式,可以让我们绑定数据对象,这样每次对象发生更改都能引发对应的改变.数据绑定最主要的目的是确保 UI 上的改变总是自动和内部的对象结构同步.在进一步讨论前,我们先看一下我们已经讨论过的问题. 数据绑定技术是在 WPF 技术之前就出现了.在 ASP.NET 中,我们通过绑定数据元素来渲染控件中适当的数据.我们通常传入一个 DataTable 并且绑

WPF——TargetNullValue(如何在绑定空值显示默认字符)

原文:WPF--TargetNullValue(如何在绑定空值显示默认字符) 说明:在数据绑定时,如果有些字段为空值,那么在数据绑定时可以用默认值来显示为空的字段. 1 <Grid> 2 <ListBox x:Name="lstPeople" Width="400"> 3 <ListBox.ItemTemplate> 4 <DataTemplate> 5 <StackPanel Orientation="

WPF中使用ObjectDataProvider绑定方法

原文:WPF中使用ObjectDataProvider绑定方法 ObjectDataProvider提供了绑定任意.net类型的功能,具体功能如下: 1.ObjectDataProvider提供了绑定任意CLR类型的公嫩那个. 2.它可以再XAML中利用生命史的语言以及参数化的构造函数完成对数据的创建 3.增加对成员函数的绑定 4.提供了更多的异步绑定的功能 下面用一个加法计算器来进行实例说明: 请先看我们的加法类: C#代码 namespace BindingDemo {     public

.NET CORE(C#) WPF简单菜单MVVM绑定

原文:.NET CORE(C#) WPF简单菜单MVVM绑定 微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF简单菜单MVVM绑定 阅读导航 本文背景 代码实现 本文参考 源码 1. 本文背景 WPF中垂直导航菜单大家应该都常用,本文介绍使用MVVM的方式怎么绑定菜单,真的很简单. 2. 代码实现 使用 .Net Core 3.1 创建名为 "MenuMVVM" 的WPF模板项目,添加两个Nug

WINFORM中加入WPF控件并绑定数据源实现跨线程自动更新

1. WINFORM中添加两个ElementHost,一个放WPF的Button,一个放WPF的TextBox.其中TextBox与数据源绑定,实现跨线程也可以自动更新,而不会出现WINFORM的TextBox控件与数据源绑定后,存在子线程中更新数据源报错(跨线程更新控件)的情况. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System