C#Datagridview - 将TextColumn转换为ComboBoxColumn

时间:2009-07-13 11:22:14

标签: c# xml winforms datagridview

我有一个包含datagridview控件的Windows窗体应用程序。 datagridview由xml文件的内容填充。目前,所有列都显示为datagridviewtextboxcolumns。我想选择一个由特定xml标记填充的内容,并在datagridviewcomboboxcolumn中显示它的内容以及其他2个选项。

实施例

<SMS>
<Number>+447931663542</Number> 
<DateTime>2009-07-12T17:00:02</DateTime> 
<Message>YES</Message> 
<FollowedUpBy>Unassigned</FollowedUpBy> 
<Outcome>Resolved</Outcome>
</SMS>

OUTCOME标记是我希望在datagridview中显示为组合列的列。例如,如果标记为空并且不包含任何数据,那么我想不显示任何内容,但是使用3个可能的选项填充了comboboxcolumn(Unresolved,Resolved,Pending)。但是,如果标签包含数据,我希望该特定项目显示在组合框中,并且可以选择其他两个选项。

非常感谢帮助实现这一目标!

此致

编辑: 目前我使用此代码:

     colOutcome = new DataGridViewComboBoxColumn();
        colOutcome.HeaderText = "Outcome";
        colOutcome.Width = 90;
        colOutcome.Items.AddRange("Resolved", "Unresolved", "Pending");
        this.dataGridView1.Columns.Insert(1, colOutcome);
        this.dataGridView1.Columns[1].Name = "OutcomeColumn";

上面的代码填充了组合框。问题是:当xml文档填充datagridview时,结果列只显示为文本框列,其中包含xml文件中结果标记之间的数据。我的观点是,我怎样才能让datagridview在读取结果列时意识到需要将其更改为组合框列,然后以这种方式显示数据,以及组合框中的其他可能选择的选项?!目前,datagridview将填充所有列作为包含数据的textboxcolumns,以及一个单独的组合框列,这不是我想要的。我需要应用程序将结果列及其数据与上面的代码合并。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

更新答案

您可以将XML文档传递给一个函数,该函数将遍历每个节点并确定它是否应该是一个ComboBox,即名称是“结果”。

private void CreateColumns(XmlDocument doc)
{
    foreach (...) // loop through each node in xml document
    {
         if (node.Name == "Outcome")
         {
              var items = new List<string>() { "Resolved", "Unresolved", "Pending" };
              this.dataGridView1.Columns.Add(CreateComboBoxColumn(node.Name, items));
         }
         else
         {
              this.dataGridView1.Columns.Add(String.Format("col{0}", node.Name), node.Name);
         }
    }
}

然后,您创建结果列的代码将是:

private DataGridViewComboBoxColumn CreateComboBoxColumn(string colHeaderText, List<string> items)
{
    var colOutcome = new DataGridViewComboBoxColumn(); 
    colOutcome.HeaderText = colHeaderText; 
    colOutcome.Width = 90; 
    colOutcome.Items.AddRange(items.ToArray());
    colOutcome.Name = String.Format("col{0}", colHeaderText);
    return colOutcome;   
}

然后,您只需在表单加载事件上调用CreateColumns并传入XML。您只需要创建一次列。

我的建议是有一个类似的功能,可以找到所有的SMS元素,并添加一个新行,用每个节点中的信息填充它。

public void MyForm_Load(object sender, EventArgs e)
{
     var doc = new XmlDocument(filename);
     CreateColumns(doc);
     CreateRows(doc);
}

希望有所帮助。

答案 1 :(得分:0)

我不是坐在VS面前所以这可能不会编译,但应该给你指路。

您需要在设计时使用3-4个可能的值预先填充ResolvedColumn,或者在运行时将其分配给另一个数据源。如果选择了设计时方法,只需打开DataGridView“编辑列”对话框,找到ResolvedColumn,转到Items,然后添加您的值(“”,“未解决”,“待定”,“已解决”)。如果有可能使用没有结果的SMS记录呈现网格,则空值可能有助于ComboBox呈现。

要在运行时绑定可能的选项,请执行以下操作:

private List<string> _outcomeDataSource;

private void Form1_Load(object sender, EventArgs e)
{
    _outcomeDataSource = new List<string>;
    _outcomeDataSource.Add("");
    _outcomeDataSource.Add("Unresolved");
    _outcomeDataSource.Add("Pending");
    _outcomeDataSource.Add("Resolved");

    ResolvedColumn.DataSource = _outcomeDataSource;
    ResolvedColumn.PropertyName = "Outcome";
}

答案 2 :(得分:0)

根据更新后的问题为我解答#2。

您遇到的问题是DataGridView的AutoGeneratedColumns功能。您需要在数据绑定之前手动创建列。这可以在设计时或运行时完成。我更喜欢设计时,因为它为你提供了更多方向的网格外观,但两种方式都有效。

您需要禁用网格的AutoGeneratedColumns属性:

private void Form1_Load(object sender, EventArgs e)
{
    // Define your columns at run-time here if that's what you prefer

    this.dataGridView1.AutoGeneratedColumns = false;
    this.dataGridView1.DataSource = myDataSource;
}