DataGrid добавляет строки, но текст не виден - PullRequest
0 голосов
/ 16 сентября 2018

Я пытаюсь отобразить DataTable на DataGrid, который имеет два столбца.

Когда я обновляю DataTable, DataGrid показывает новые строки, но ячейки пусты. Я просмотрел много разных возможных решений для этого и до сих пор не смог отобразить результаты.

Вот мой код xaml для DataGrid:

<DataGrid x:Name="SubjectsList" Height="500" ScrollViewer.CanContentScroll="True" AutoGenerateColumns="False" CanUserAddRows="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Subject" Width="2*"/>
        <DataGridTextColumn Header="Weekly" Width="*"/>
    </DataGrid.Columns>
</DataGrid>

Ниже приведен мой код C # для обновления таблицы:

public void AddSubject(object sender, RoutedEventArgs e)
{
    Subject temp = new Subject(SubjectName.Text, Convert.ToInt32(PerWeek.Text));

    subjects.Add(temp);
    MessageBox.Show(temp.Name + " has been added");

    for(int i = 0; i < subjectsTable.Rows.Count; i++)
    {
        subjectsTable.Rows.RemoveAt(i);
    }

    foreach (Subject subject in subjects)
    {
        DataRow dataRow = subjectsTable.NewRow();
        dataRow[0] = subject.Name;
        dataRow[1] = subject.ClassesPerWeek;
        subjectsTable.Rows.Add(dataRow);
        MessageBox.Show(subject.Name);
    }

    SubjectsList.ItemsSource = subjectsTable.DefaultView;
}

В приведенном выше коде SubjectsList - это моя DataGrid, а subjectsTable - это моя DataTable.

Я пробовал следующее:

  1. Используйте DataGrid.DataContext вместо DataGrid.ItemSource
  2. Добавлено ItemSource = "{Binding Path=subjectsTable}" в моем коде xaml
  3. Попытка добавить строки как элементы, используя DataGrid.Items.Add(dataRow)
  4. Добавлен метод getter и setter для каждого члена данных моего пользовательского класса Subject
  5. Все мои переменные, члены данных и структуры данных являются общедоступными.

Если кто-нибудь знает, как сделать данные видимыми, то, пожалуйста, помогите мне. Спасибо.

Вот что происходит после добавления двух предметов:

Output of DataGrid

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Необходимо указать привязку для каждого столбца в DataGrid.

Пути привязки будут именами столбцов в DataTable.

Предполагается, что ваши столбцы DataTable определены следующим образом (вы не показывали это, поэтому мне пришлось просто привести пример):

subjectsTable.Columns.Add("NameColumn", typeof(string));
subjectsTable.Columns.Add("ClassesColumn", typeof(int));

Определения столбцов DataGrid в XAML должны выглядеть следующим образом:

<DataGridTextColumn Header="Subject" Width="2*" Binding="{Binding NameColumn}"/>
<DataGridTextColumn Header="Weekly" Width="*" Binding="{Binding ClassesColumn}"/>

Альтернатива - установить для свойства AutoGenerateColumns DataGrid значение true и опустить определения столбцов в XAML. Но тогда у вас не так много контроля над сеткой.

0 голосов
/ 16 сентября 2018

В случае, если вы хотите рассмотреть использование шаблона MVVM (https://intellitect.com/getting-started-model-view-viewmodel-mvvm-pattern-using-windows-presentation-framework-wpf/),, вот базовая реализация:

Создайте свою модель представления:

       public class ViewModel : INotifyPropertyChanged
       {
        public ViewModel()
        {
            CreateTestData();
            AddSubjectCommand = new Command(AddSubject);
        }

        public ICommand AddSubjectCommand { get; }

        private ObservableCollection<Subject> _subjects;
        public ObservableCollection<Subject> Subjects
        {
            get => _subjects;
            set
            {
                _subjects = value;
                OnPropertyChanged();
            }
        }

        public void AddSubject()
        {
            Subjects = new ObservableCollection<Subject>();
            DataTable subjectsTable = new DataTable();

            foreach (Subject subject in subjects)
            {
                //DataRow dataRow = subjectsTable.NewRow();
                //dataRow[0] = subject.Name;
                //dataRow[1] = subject.ClassesPerWeek;
                //subjectsTable.Rows.Add(dataRow);

                Subjects.Add(new Subject
                {
                    Name = subject.Name,
                    ClassesPerWeek = subject.ClassesPerWeek
                });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #region Test data

        public IList<Subject> subjects { get; set; }

        private void CreateTestData()
        {
            subjects = new List<Subject>();
            subjects.Add(new Subject { Name = "Subject 1", ClassesPerWeek = 5 });
            subjects.Add(new Subject { Name = "Subject 2", ClassesPerWeek = 10 });
        }

        #endregion
        }

Материал, который вам нужно понять здесь:

  1. ObservableCollection: https://www.c -sharpcorner.com / UploadFile / e06010 / observablecollection-in-wpf /
  2. INotifyPropertyChanged: https://www.c -sharpcorner.com / article / use-inotifypropertychanged-interface-in-wpf-mvvm /
  3. ICommand: https://www.c -sharpcorner.com / UploadFile / e06010 / wpf-icommand-in-mvvm /

Создайте команду, которая реализует ICommand:

public class Command : ICommand
    {
        private readonly Action _action;
        private readonly bool _canExecute;

        public Command(Action action, bool canExecute = true)
        {
            _action = action;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute;
        }

        public void Execute(object parameter)
        {
            _action();
        }

        public event EventHandler CanExecuteChanged;
    }

Кодовый код (не правда ли?):

 public partial class MainWindow
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }
    }

Xaml:

<Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Button Content="Add Subject" Command="{Binding AddSubjectCommand}" Width="100" Height="30" HorizontalAlignment="Left" />
        <DataGrid Grid.Row="1" x:Name="SubjectsList" ItemsSource="{Binding Subjects}" Height="500" ScrollViewer.CanContentScroll="True" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Subject" Width="100">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Weekly" Width="100">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding ClassesPerWeek}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

См. Следующее:

  1. DataContext - это модель представления
  2. Источник элементов сетки - моя коллекция ObservableCollection
  3. Команда кнопки привязана к AddSubjectCommand, который находится в ViewModel

Пример вывода

enter image description here

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...