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>

  

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

      好多人在评论里要DEMO,我没有时间去一个一个发,直接就把前面例子的DEMO放这了,大家自行下载吧!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPFDataGridComboBoxColumn是一种用于数据网格控件的列类型,它可以显示ComboBox下拉列表,并且可以使用Converter将不同的数据进行绑定。 Converter是WPF中的一个重要概念,它可以在数据绑定过程中进行值的转换。使用Converter可以帮助我们在绑定ComboBox时,将不同的数据进行转换和展示。 使用Converter绑定不同数据的步骤如下: 1. 首先,我们需要创建一个实现了IValueConverter接口的Converter类。这个Converter类负责将源数据转换为目标数据。例如,我们可以将一个int类型的数据转换为对应的字符串类型数据。 2. 接下来,在XAML文件中创建DataGridComboBoxColumn列,并设置Binding属性为对应的数据源。可以使用ItemsSource属性来绑定ComboBox的数据源,可以使用SelectedItemBinding属性来绑定选中的项。同时,使用Converter属性将Converter类与该列的数据绑定进行关联。 3. 在Converter类中,实现Convert方法和ConvertBack方法。Convert方法用于将源数据转换为目标数据,而ConvertBack方法则用于将目标数据转换回源数据。 通过上述步骤,我们就可以实现在DataGridComboBoxColumn列中使用Converter绑定不同的数据。 总结起来,WPFDataGridComboBoxColumn通过使用Converter可以实现将不同的数据进行绑定和展示。使用Converter可以将源数据转换为目标数据,从而实现ComboBox的数据源绑定和数据项的转换。通过掌握这种使用方式,我们可以更灵活地使用DataGridComboBoxColumn列,并展示不同类型的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值