【问题标题】:At Runtime Add X number of ComboBoxes with SelectedItem to DataGrid (WPF)在运行时将 X 个带有 SelectedItem 的组合框添加到 DataGrid (WPF)
【发布时间】:2018-11-15 05:31:30
【问题描述】:

我想在DataGrid 中创建一整行ComboBoxes。我在以下方面取得了一些进展:

// Declare it
private DataGridComboBoxColumn CreateCustomComboBoxDataSouce(string ColumnName) 
{
    string[] data = { "Date", "LEInt", "String" };
    DataGridComboBoxColumn dgCmbCol = new DataGridComboBoxColumn();
    dgCmbCol.Header = ColumnName;
    dgCmbCol.ItemsSource = data;
    return dgCmbCol;
}

// Later somewhere you can add this to create 20 columns:
for (int i = 0; i < 20; i++)
{
  DataGridComboBoxColumn newColumn = CreateCustomComboBoxDataSouce("Column-" +i);
}
// Sadly nothing is shown unless you manually specify a new row and an
// extra column as done here below, but then you get an extra column.
DataTable table = new DataTable();
table.Columns.Add("|", typeof(string));
table.Rows.Add("");
DataGridCombo.DataContext = table;

XAML 保持在最低限度:

<DataGrid x:Name="DataGridCombo" ItemsSource="{Binding}"   Margin="0,0,0,0" />

有没有办法设置每个ComboBox 的默认SelectedValue?在我的for 循环中,我确实可以访问所需的设置。另外,有没有办法让它显示而不添加额外的列?此 DataGrid 正在与另一个没有额外列的 DataGrid 对齐。

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    有没有办法设置每个ComboBox的默认SelectedValue

    DataColumn 添加到DataTableDataGridComboBoxColumn,然后将每行的列值设置为所需的选定值:

    const int n = 20;
    DataTable table = new DataTable();
    for (int i = 0; i<n; i++)
    {
        string columnName = "Column-" + i;
        DataGridCombo.Columns.Add(CreateCustomComboBoxDataSouce(columnName));
        table.Columns.Add(columnName, typeof(string));
    }
    table.Rows.Add(new object[n]);
    //select some values...
    table.Rows[0][1] = "LEInt";
    table.Rows[0][5] = "String";
    DataGridCombo.DataContext = table;
    

    另外,有没有办法在不添加额外列的情况下显示它?

    HorizontalAlignment 属性设置为Left 以防止DataGrid 水平拉伸:

    <DataGrid x:Name="DataGridCombo" ItemsSource="{Binding}" HorizontalAlignment="Left" />
    

    【讨论】:

    • 非常感谢 mm8,当我出于某种原因尝试这样做时,我有 20 个空白列,然后在索引 [0][1] 上超过 2 个(在位置 22)我得到 LEInt 作为一个字符串没有下拉功能,然后我得到String for [0][5]。当我设置断点并检查 table 时,它只有 20 个项目,并且设置在正确的位置。我认为问题在于,在 for 循环中是 DataGridCombo.Columns.Add(CreateCustomComboBoxDataSouce(columnName));,它将所有这些添加到 DataGrid,然后将 table 附加到末尾。我们可以将ComboBox 添加到DataTable 吗?
    • 我刚刚注意到一些事情。我通常关闭标题,但 DataGrid 有名为 Column-0 -Column-19 的列,然后附加到末尾的是 Column-0 -Column-19,第二组是设置 LEIntString 的位置。通常我认为列名必须是唯一的,但我猜是因为 DataType 不同,所以允许重复?
    • 它对我来说很好,所以你显然做错了什么。
    • 非常感谢 mm8 付出的时间和精力。我创建了一个示例空项目并粘贴了代码并遇到了同样的问题。这是一段视频,展示了发生在我身上的事情:streamable.com/0kghj
    【解决方案2】:

    在对这个问题进行了大量工作后,我最终得出结论,我试图做的事情要么是不可能的,要么是不合理的。我改为使用水平方向的StackPanel。以下是相关的sn-ps:

    //XAML Layout
    <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Name="ComboBoxPanel"  Grid.Row="1"  Margin="0,0,0,0"  HorizontalAlignment="Left" />
    
    //Function to create new box and set options
    private ComboBox CreateComboBox(string ColumnName, string selectedItem, int width)
    {
        string[] data = { "Date", "LEInt", "String" };
    
        ComboBox dgCmbCol = new ComboBox();
        dgCmbCol.ItemsSource = data;
        dgCmbCol.Name = ColumnName;
        dgCmbCol.Width = width;
        dgCmbCol.SelectedItem = selectedItem;
        dgCmbCol.SelectionChanged += DataTypeSelectionChanged;
        return dgCmbCol;
    }
    
    // This reads a JSON file and uses it's options to set the width of all the columns
    // for the DataGrid and matches the ComboBoxes to it so they all line up
    dynamic TableData = JsonConvert.DeserializeObject(Config.DataLayoutDefinition);
    ComboBoxPanel.Children.Clear(); //Since this is run on user interaction, clear old contents.
    
    for (int i = 0; i <  DataGridView.Columns.Count; i++)
    {
        int width = TableData.data[i].ColumnWidth;
        if (TableData.data[i].DataType == "String")
        {
            width = 125;
        }
        else if (TableData.data[i].DataType == "Date")
        {
            width = 150;
        }
        else if (TableData.data[i].DataType == "LEInt")
        {
            width = 80;
        }
        else
        {
            width = 100;
        }
    ComboBoxPanel.Children.Add(CreateComboBox(TableData.data[i].Column.ToString(), TableData.data[i].DataType.ToString(), width));
        DataGridView.Columns[i].Width = width;
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2011-02-24
      • 2014-10-14
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多