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

參考:

多個忘了來源的博客。感謝之。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章