как установить ширину столбца с данными и как установить цвет столбца с данными при некоторых условиях - PullRequest
0 голосов
/ 04 июня 2019

В файле xaml.cs (приложение WPF) Я создал DataTable с 3 столбцами. Требуется установить ширину второго столбца только в xaml.cs.Кроме того, вы хотите установить синий цвет фона первой строки второго столбца (только для ячейки, которая находится в первом ряду и во втором столбце).

Создано 3 столбца как: DataTable dt = new DataTable ();dt.Columns.Add (new DataColumn ("ABC"); Точно так же добавили еще 2 столбца.

Хотите установить ширину второго столбца

1 Ответ

0 голосов
/ 06 июня 2019

Я не совсем уверен, если это то, что вы ищете, но это то, что я бы сделал

Во-первых: допустим, вы создали базовую таблицу данных и заполнили еес некоторыми значениями, такими как:

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

, который выглядит так в отладчике:

enter image description here

Секунда: Получите некоторый VisualElement для отображения ваших данных.Я бы предложил использовать DataGrid для.Итак, откройте свой MainWindows.xaml и добавьте DataGrid к вашему Grid с 3 DataGridTextColumns следующим образом:

    <DataGrid>
    </DataGrid>

Поскольку мы хотим добавить свойства custiom в наши столбцы, мы должны добавитьAutoGenerateColumns="False" в нашу DataGrid, если мы этого не сделаем, DataGrid автоматически сгенерирует свои столбцы на основе его ItemsSource.Поскольку теперь мы не получим автоматически сгенерированные столбцы, мы также должны добавить 3 столбца, напоминающих 3 столбца из нашей таблицы данных:

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

Третий: Далее мы должны установить ItemsSource наших DataGrid.К сожалению, DataGrid не может обработать DataTable, поэтому сначала нужно преобразовать наш DataTable во что-то, что DataGrid может прочитать.Давайте сгенерируем для этого новый класс и назовем его 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));
        }
    }
}

Он имеет свойства и PropertyChangedEventHandler, который будет уведомлять ваш VisualElement при изменении свойства.

Четвертый: DataGrid не принимает DataTables, но принимает Lists и ObserableCollections.Используйте List, если вы не хотите добавлять / изменять элементы во время выполнения.Я буду использовать ObserableCollection, для работы которого нужно using System.Collections.ObjectModel;.

Создайте свойство вашего списка и добавьте 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));
        }
    }
}

Следующим шагом будетчтобы преобразовать ваш 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: Ваш список заполненМодели, следующим шагом будет рассказать вашему 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>

, и вы увидите DataGridworks:

enter image description here

Sixth: Последний шаг - фактически установить свойства ваших столбцов, что довольно просто, вашТребования будут выглядеть примерно так:

<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 в Code, как вы хотели, но это все равно было бы плохой практикой.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}" />

Это не совсем то, что вы хотели, но я надеюсь, что это поможет любым способом.

...