如何设置数据表列的宽度以及如何在某些情况下设置数据表列的颜色

how to set the width of datatable column and how to set the color of datatable column upon some condition

IN xaml.cs 文件(WPF 应用程序)我创建了一个包含 3 列的数据表 只想在 xaml.cs 中设置第二列的宽度。 另外,要将第二列第一行背景颜色设置为蓝色(仅适用于第一行第二列中的单元格)。

已创建 3 列: DataTable dt= new DataTable(); dt.Columns.Add(新数据列("ABC"); 同样,又添加了 2 列。

要设置第二列的宽度

我不太确定,如果这就是你要找的,但这是我会做的

首先: 假设您创建了一个基本的 DataTable 并用一些值填充它,如下所示:

        DataTable dt = new DataTable();
        dt.Columns.Add("Key", typeof(int));
        dt.Columns.Add("Material", typeof(string));
        dt.Columns.Add("Price per Kilo", typeof(int));

        dt.Rows.Add(1, "CobbleStone", 34);
        dt.Rows.Add(2, "Wooden Planks", 12);
        dt.Rows.Add(3, "Iron Ingots", 56);

在调试器中看起来像这样:

其次:获取一些 VisualElement 来显示您的数据。我建议使用 DataGrid for。所以去你的 MainWindows.xaml 并添加一个 DataGrid 到你的 Grid 和 3 DataGridTextColumns 像这样:

    <DataGrid>
    </DataGrid>

因为我们要向我们的列添加自定义属性,所以我们必须向我们的 DataGrid 添加 AutoGenerateColumns="False",否则 DataGrid 将根据其 ItemsSource 自动生成其列。由于我们现在不会获得任何自动生成的列,因此我们还必须添加 3 列,类似于数据表中的 3 列:

    <DataGrid AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Key" />
            <DataGridTextColumn Header="Material" />
            <DataGridTextColumn Header="Price per Kilo" />
        </DataGrid.Columns>
    </DataGrid>

第三: 接下来我们要设置我们的DataGridItemsSource。不幸的是 DataGrid 无法处理 DataTable,因此我们首先必须将 DataTable 转换为 DataGrid 可以读取的内容。让我们为此生成一个新的 Class 并将其命名为 MaterialModel,如下所示:

using System.ComponentModel;
using System.Runtime.CompilerServices;

class Model : INotifyPropertyChanged
{

    private int m_Key;
    public int Key
    {
        get
        {
            return m_Key;
        }
        set
        {
            m_Key = value;
            OnPropertyChanged("Key");
        }
    }


    private string  m_Name;
    public string  Name
    {
        get
        {
            return m_Name;
        }
        set
        {
            m_Name = value;
            OnPropertyChanged("Name");
        }
    }
    private int m_Price;
    public int Price
    {
        get
        {
            return m_Price;
        }
        set
        {
            m_Price = value;
            OnPropertyChanged("Price");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

它有属性和一个 属性ChangedEventHandler,它将在 属性 更改时通知您的 VisualElement。

第四:DataGrid不接受DataTables,但接受ListsObserableCollections。如果您不想在运行时 add/change 您的项目,请使用 List。我将使用 ObserableCollection,它需要 using System.Collections.ObjectModel; 才能工作。

为您的列表创建一个 属性 并向 MainWindow 添加一个 属性ChangedEventHandler。

    public partial class MainWindow : Window
{

    private ObservableCollection<MaterialModel> m_MaterialList;
    public ObservableCollection<MaterialModel> MaterialList
    {
        get
        {
            return m_MaterialList;
        }
        set
        {
            m_MaterialList = value;
            OnPropertyChanged("MaterialList");
        }
    }

    public MainWindow()
    {
        // [...]
    }



    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

下一步是将您的 DataTable 转换为 ObservableCollection,因此遍历您的 DataTable 并将每一行转换为您的模型之一,如下所示:

        MaterialList = new ObservableCollection<MaterialModel>();
        foreach(DataRow row in dt.Rows)
        {
            MaterialModel model = new MaterialModel
            {
                Key = int.Parse(row["Key"].ToString()),
                Name = row["Material"].ToString(),
                Price = int.Parse(row["Price per Kilo"].ToString()),
            };
            MaterialList.Add(model);
        }

第五: 你的列表中充满了模型,下一步是告诉你的 DataGrid 如何使用你的列表。首先,将您的列表绑定到 ItemsSource auf 您的 DataGrid,然后将每个 DataGridTextColumn 绑定到您的 MaterialModel 中的一个属性,如下所示:

        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding MaterialList}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Key" Binding="{Binding Key}" />
            <DataGridTextColumn Header="Material" Binding="{Binding Name}" />
            <DataGridTextColumn Header="Price per Kilo" Binding="{Binding Price}" />
        </DataGrid.Columns>
    </DataGrid>

您将看到 DataGrid 起作用:

第六步:最后一步是实际设置列的属性,这很简单,您的要求如下所示:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding MaterialList}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Key" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Key}" Background="LightBlue"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="Material" Binding="{Binding Name}" Width="300" />
            <DataGridTextColumn Header="Price per Kilo" Binding="{Binding Price}"  />
        </DataGrid.Columns>
    </DataGrid>

我还没有找到一种方法来完全按照您的意愿在代码隐藏中创建 DataGrid,但无论如何这将被认为是不好的做法。 WPF 旨在使用 xaml 和 c#.

之间的这种连接

如果您想在 C# 中管理您的列属性,这将是一个正确的方法:

在你的 MainWindow.xaml.cs:

        private double m_SecondColumnWidth;
    public double SecondColumnWidth
    {
        get
        {
            return m_SecondColumnWidth;
        }
        set
        {
            m_SecondColumnWidth = value;
            OnPropertyChanged("SecondColumnWidth");
        }
    }

   public MainWindow()
    {

        SecondColumnWidth = 300;     
   }

XAML:

    <!-- right beneath your Grid -->
    <Grid.Resources>
        <local:ViewModel x:Key="viewModel" />
    </Grid.Resources>

   <DataGridTextColumn Header="Material" Binding="{Binding Name}" Width="{Binding Source={StaticResource viewModel}, Path=SecondColumnWidth}" />

这不是您想要的,但我希望它能对您有所帮助。