WPF DataGrid ComboBox 下拉框数据绑定。且默认显示下拉框,可与其他列绑定联动。

这段时间在折腾 WPF 的表格控件。为了实现表格里带下拉框,同时联动另一列,真是想的快吐了。
完整版代码放在文末,先展示最终方案:

方案也是改了又改, 从直接的 DataGridComboBoxColumn 到 DataGridTemplateColumn的 CellEditingTemplate 再到这个完成版 DataGridTemplateColumn的CellTemplate 加事件。

第一版:

能显示,可惜不能保存修改,不能联动其他列。

<DataGridComboBoxColumn Header="单位" SelectedItemBinding="{Binding UnitStr}" ItemsSource="{Binding UnitList}"/>

第二版:
能显示,能保存,能联动其他列,就是不能默认显示为下拉框。必须点击后,才会出现下拉框。而且保存必须按回车键...

<DataGridTemplateColumn Header="单位EU" Width="2*">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="3*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding UnitStr, Mode=OneWay}" />
                <Image Grid.Column="1" Width="5" Height="5" Source="/SensorMonitoring;component/UserRes/DownArrow.png" />
            </Grid>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox Tag="{Binding idx}" IsEditable="{Binding isUnitFreeInput}" Text="{Binding UnitStr}" ItemsSource="{Binding unitList}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
public string UnitStr
{
	get
	{
		return this.unitstr;
	}
	set
	{
		this.unitstr = value;
                  //联动其他列
		if (this.sType.Contains("压力"))
		{
			this.TCoef_K = CurrencyAgreement.PUnits.GetRatioNum(this.unitstr);
			this.TCoef_B = 0f;
		}
		this.PropertiesC();
	}
}	

第三版 也是最终版    :
能显示,能保存,能联动其他列,而且默认显示为下拉框。
要点有两个
1 DataGridTemplateColumn 加 CellTemplate的ComboBox。保证了能直接显示下拉框。
2 CellTemplate.ComboBox 的SelectionChanged 事件。 只有CellTemplate 的SelectionChanged事件才会触发。也由此 可以在这个事件中手动保存 列值UnitStr 。以及联动其他列。

<DataGrid Name="dataGrid0" ItemsSource="{Binding}" AutoGenerateColumns="False" SelectionMode="Single"
    SelectionUnit="Cell" CanUserSortColumns="False" CanUserReorderColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="变换系数K" Width="2*" Binding="{Binding CoefK}" />
        <DataGridTemplateColumn Header="单位EU" Width="2*" >
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox x:Name="cellComboBox0" Tag="{Binding Idx}"  SelectedItem="{Binding UnitStr}" ItemsSource="{Binding UnitList}" SelectionChanged="ComboBox_SelectionChanged"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
	var cb = (sender as ComboBox);
	if (cb == null || cb.Tag == null) return;
	int idx = int.Parse(cb.Tag.ToString());
   // var bindDataGridDatas = this.dataGrid0.ItemsSource as BindDataGridData[];//成员变量和这里转换都可以。
	bindDataGridDatas[idx].UnitStr = (string)cb.SelectedItem;//手动保存到数据结构
	bindDataGridDatas[idx].UpdateKBValue(); //联动CoefK值
}
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApp2.DataGrid
{
    class BindDataGridData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void PropertiesC([CallerMemberName] string propertyName = "")
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public int Idx { get; set; } = 0;

        string unitstr = "Pa";

        public string UnitStr
        {
            get
            {
                return this.unitstr;
            }
            set
            {
                this.unitstr = value;
                this.PropertiesC();
            }
        }

        public string[] UnitList { get; set; } = new string[] { "Pa", "kPa", "MPa" };

        public static readonly float[][] KBList = new float[][] { new float[] { 1, 1 }, new float[] { 1000, 2 }, new float[] { 1000000, 3 } };

        float coefK { get; set; } = 1f;

        public float CoefK
        {
            get
            {
                return this.coefK;
            }
            set
            {
                this.coefK = value;
                this.PropertiesC();
            }
        }

        public void UpdateKBValue()
        {
            int idx = -1;
            for (int j = 0; j < this.UnitList.Length; j++)
            {
                if (this.UnitList[j] == this.unitstr)
                {
                    idx = j; break;
                }
            }
            if (idx == -1) return;
            //throw new System.Exception("no Unit in UnitList:  unit " + this.UnitStr + " UnitList {" + string.Join(", ", this.UnitList)+"}");

            this.CoefK = BindDataGridData.KBList[idx][0];
        }
    }
}

参考:

多个忘了来源的博客。感谢之。

已标记关键词 清除标记
我想在表格中datagrid控件中动态添加下拉框,现有以下代码,但做出来的东西还是无法正确显示,应该怎么做: namespace DataGridBackColor { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private DataTable dtData; ComboBox comboBox = new ComboBox(); private void Form1_Load(object sender, EventArgs e) { init_WareHouse(); // comboBox.Visible = false; this.dgv_User.Controls.Add(comboBox); } private void initData() { dtData = new DataTable(); dtData.Columns.Add("物料名称"); dtData.Columns.Add("库房地址"); dtData.Columns.Add("库位地址"); dtData.Columns.Add("物料编码"); dtData.Columns.Add("交货数量"); dtData.Columns.Add("(单位)"); DataRow drData; drData = dtData.NewRow(); drData[0] ="啊啊啊啊"; drData[1] = "bbbbbbb"; drData[2] = "ccccccccc"; drData[3] = "545455554"; drData[4] = "1"; drData[5] = "PC"; dtData.Rows.Add(drData); this.dgv_User.DataSource = dtData; } private void init_WareHouse() { DataTable dtShelf = new DataTable(); dtShelf.Columns.Add("Value"); dtShelf.Columns.Add("Name"); //String[] temp_ShelfInfo = ShelfInfo[i].Split(','); DataRow drShelf; drShelf = dtShelf.NewRow(); drShelf[0] ="二级库"; drShelf[1] ="4545454545"; dtShelf.Rows.Add(drShelf); comboBox.ValueMember = "Value"; comboBox.DisplayMember = "Name"; comboBox.DataSource = dtShelf; comboBox.DropDownStyle = ComboBoxStyle.DropDownList; this.dgv_User.Controls.Add(comboBox); } private void Serach_Click(object sender, EventArgs e) { initData(); } private void dgv_User_CurrentCellChanged(object sender, EventArgs e) { try { if (this.dgv_User.CurrentCell.ColumnNumber==1) { MessageBox.Show("ddddd"); Rectangle rect = new Rectangle(dgv_User.CurrentCell.ColumnNumber, dgv_User.CurrentCell.RowNumber,10,20); comboBox.Left = rect.Left; comboBox.Top = rect.Top; comboBox.Width = rect.Width; comboBox.Height = rect.Height; comboBox.Visible = true; } } catch { } } } }
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页