簡體   English   中英

C# WPF - 我如何動態地創建一個帶有動態列的 DataGrid(每列的存在取決於用戶輸入)

[英]C# WPF - How can I dynamically make a DataGrid with dynamic columns (the existence of each column depends on the user input)

這是我試圖在 xaml 上制作的那種表:

用戶輸入將始終是一個 char 字符串,該表將始終有 2 行,數據將始終是雙倍的。 列數根據用戶輸入的字符串的長度而變化。 用戶將無法通過界面編輯表格。

我是 WPF 和 C# 的新手,我在這里遇到了一個非常大的障礙,感謝所有幫助

如果您需要動態列,則應始終使用DataTable作為數據源。 這樣,您可以避免在 C#/code-behind 中顯式構建DataGrid ,而是使用自動生成功能。

示例中使用的兩個輔助方法AddColumnAddRow是作為DataTable的擴展方法實現的候選方法。

主窗口.xaml.cs

private void OnSendButtonClick(object sender, EventArgs e)
{
  var dataGridSource = new DataTable();

  AddColumn<string>(dataGridSource, "type");
  foreach (char character in this.TextInput.Text)
  {
    AddColumn<double>(dataGridSource, character.ToString());
  }

  // Generate 2 rows of pseudo data
  var doubleGenerator = new Random();
  for (int rowIndex = 0; rowIndex < 2; rowIndex++)
  {
    var columnValues = new List<object>();
    columnValues.Add(rowIndex < 1 ? "x" : "y");
    for (int columnIndex = 0; columnIndex < dataGridSource.Columns.Count; columnIndex++)
    {
      columnValues.Add(doubleGenerator.NextDouble());
    }
    AddRow(dataGridSource, columnValues);
  }

  this.Table.ItemsSource = dataGridSource.DefaultView;
}

private void AddColumn<TData>(DataTable dataTable, string columnName, int columnIndex = -1)
{
  DataColumn newColumn = new DataColumn(columnName, typeof(TData));

  dataTable.Columns.Add(newColumn);
  if (columnIndex > -1)
  {
    newColumn.SetOrdinal(columnIndex);
  }

  int newColumnIndex = dataTable.Columns.IndexOf(newColumn);

  // Initialize existing rows with default value for the new column
  foreach (DataRow row in dataTable.Rows)
  {
    row[newColumnIndex] = default(TData);
  }
}

private void AddRow(DataTable dataTable, IList<object> columnValues)
{
  DataRow rowModelWithCurrentColumns = dataTable.NewRow();
  dataTable.Rows.Add(rowModelWithCurrentColumns);

  for (int columnIndex = 0; columnIndex < dataTable.Columns.Count; columnIndex++)
  {
    rowModelWithCurrentColumns[columnIndex] = columnValues[columnIndex];
  }
}

主窗口.xaml

<Window>
  <StackPanel>
    <TextBox x:Name="TextInput" />
    <Button Content="Send"
            Click="OnSendButtonClick" />
    <DataGrid x:Name="Table" />
  </StackPanel>
</Window>

(代碼隱藏)

//clear rows & columns
DataGrid.Items.Clear();
DataGrid.Columns.Clear();

//add type Column
DataGridTextColumn typeColumn = new DataGridTextColumn();
typeColumn.Header = "Type";
typeColumn.Binding = new Binding("Type");
DataGrid.Columns.Add(typeColumn);

//Define rows
var xRow = new ExpandoObject() as IDictionary<string, object>;
var yRow = new ExpandoObject() as IDictionary<string, object>;
xRow.Add("Type", "X");
yRow.Add("Type", "Y");

//Get user input
string input = UserInput.Text;

//Add columns
for (int i = 0; i < input.Length; i++)
{
    DataGridTextColumn column = new DataGridTextColumn();
    column.Header = input[I];
    column.Binding = new Binding(input[i].ToString());
    DataGrid.Columns.Add(column);

    //fill data
    xRow.Add(input[i].ToString(), 1.1);
    yRow.Add(input[i].ToString(), 1.1);
}

//Add rows
DataGrid.Items.Add(xRow);
DataGrid.Items.Add(yRow);

這種方法的問題是用戶不能因為 Dictionary 而添加相同的字母/列兩次,但您可以調整和更改代碼以滿足您的需要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM