简体   繁体   English

如何设置datatable列的宽度以及如何在某些条件下设置datatable列的颜色

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

IN xaml.cs file(WPF Application) I have created a DataTable with 3 columns Wanted to set the second column's width in xaml.cs only. IN xaml.cs文件(WPF应用程序)我创建了一个包含3列的DataTable,只想在xaml.cs中设置第二列的宽度。 Also, want to set the second columns first row background color to blue(only for the cell which is in first row and 2nd column). 另外,要将第二列第一行背景颜色设置为蓝色(仅适用于第一行和第二列中的单元格)。

Have created 3 columns as : DataTable dt= new DataTable(); 创建了3列:DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("ABC"); Similarly, have added 2 more columns. dt.Columns.Add(new DataColumn(“ABC”);同样,又添加了2列。

Want to set the second columns width 想要设置第二列宽度

I am not fairly certain, if this is what you are looking for, but it is what I would do 我不太确定,如果这是你正在寻找的,但这是我会做的

First: let's say you have created a basic DataTable and filled it with some values, like this: 首先:假设您已经创建了一个基本的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);

which looks like this in the debugger: 在调试器中看起来像这样:

在此输入图像描述

Second: Get some VisualElement to display your Data. 第二:获取一些VisualElement来显示您的数据。 I'd suggest using a DataGrid for. 我建议使用DataGrid So go your your MainWindows.xaml and add a DataGrid to your Grid with 3 DataGridTextColumns like this: 所以,你去你的MainWindows.xaml和添加DataGrid到您的Grid 3个DataGridTextColumns是这样的:

    <DataGrid>
    </DataGrid>

Since we want to add custiom properties to our Columns, we have to add AutoGenerateColumns="False" to our DataGrid, if we don't the DataGrid will automatically generate its columns based on its ItemsSource. 由于我们要向我们的列添加custiom属性,我们必须向DataGrid添加AutoGenerateColumns="False" ,如果我们不这样做,DataGrid将根据其ItemsSource自动生成其列。 Since we won't get any autogenerated Columns now, we also have to add 3 Columns resembling the 3 columns from our DataTable: 由于我们现在不会获得任何自动生成的列,我们还必须添加3个类似于DataTable中3列的列:

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

Third: Next we have to set the ItemsSource of our DataGrid . 第三:接下来我们必须设置DataGridItemsSource Unfortunately a DataGrid can't process a DataTable , so we first have to convert our DataTable into something the DataGrid can read. 不幸的是, DataGrid无法处理DataTable ,因此我们首先必须将DataTable转换为DataGrid可以读取的内容。 Let's generate a new Class for this and call it MaterialModel , which looks like this: 让我们为此生成一个新类,并将其称为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));
        }
    }
}

It has Properties and a PropertyChangedEventHandler, which will notify your VisualElement when the Property changes. 它具有Properties和PropertyChangedEventHandler,它将在Property更改时通知您的VisualElement。

Fourth: The DataGrid doesn't accept DataTables , but it accepts Lists and ObserableCollections . 第四: DataGrid不接受DataTables ,但它接受ListsObserableCollections Use a List , if you don't want to ever add/change your items at runtime. 如果您不想在运行时添加/更改项目,请使用List I'll use an ObserableCollection , which neeeds using System.Collections.ObjectModel; 我将使用ObserableCollection ,它using System.Collections.ObjectModel; to work. 上班。

Create a Property of your List and add a PropertyChangedEventHandler to MainWindow. 创建List的属性并将PropertyChangedEventHandler添加到MainWindow。

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

The next step would be to convert your DataTable into a ObservableCollection , so iterate through your DataTable and Convert each Row to one of your Models, like this: 下一步是将您的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);
        }

Fivth: Your List is filled with Models, the next step would be to tell your DataGrid how to use your List. Fivth:你的列表中充满了Models,下一步就是告诉你的DataGrid如何使用你的List。 First, bind your List to the ItemsSource auf your DataGrid , then bind each DataGridTextColumn to one of the Properties in your MaterialModel, like this: 首先,你的列表绑定到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>

and you'll see the DataGrid works: 你会看到DataGrid的工作原理:

在此输入图像描述

Sixth: The last step is to actually set the properties of your columns, which is pretty easy, your Requirements would look something like this: 第六最后一步是实际设置列的属性,这非常简单,您的需求看起来像这样:

<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>

I haven't found a way to create a DataGrid completely in Code behind as you wanted, but this would be cosnidered bad practice anyway. 我还没有找到一种方法在你想要的后面完全在Code中创建一个DataGrid,但无论如何这都是错误的做法。 WPF is designed to use this connection between xaml und c#. WPF旨在使用xaml和c#之间的此连接。

If you want to manage your column properties in c# anyways, this would be a proper way to do it: 如果你想在c#中管理你的列属性,这将是一个正确的方法:

in your MainWindow.xaml.cs: 在您的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: 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}" />

This isn't exactly what you wanted, but I hope it helps any way. 这不是你想要的,但我希望它有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM