wpf DataGrid添加行,但文本不可见

juud5qan  于 2022-11-26  发布在  其他
关注(0)|答案(3)|浏览(277)

我正在尝试将DataTable显示到具有两列的DataGrid上。
当我更新DataTable时,DataGrid会显示新的数据列,但储存格是空的。我已经针对这个问题寻找过许多不同的可能解决方案,但仍然无法显示结果。
下面是我为DataGrid编写的xaml代码:

<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是我的数据网格,subjectsTable是我的数据表。
我已尝试以下方法:
1.使用DataGrid.DataContext代替DataGrid.ItemSource
1.在我的xAML代码中添加了ItemSource = "{Binding Path=subjectsTable}"
1.尝试使用DataGrid.Items.Add(dataRow)将行作为项添加
1.为我的用户定义类Subject的每个数据成员添加了gettersetter方法
1.我的所有变量、数据成员和数据结构都是公共的。
如果有人知道如何使数据可见,那么请帮助我。谢谢。
下面是添加两个主题后的情况:

x0fgdtte

x0fgdtte1#

您需要为DataGrid中的每一列指定绑定。
绑定路径将是DataTable中列的名称。
假设您的DataTable列是这样定义的(您还没有演示这一点,所以我只能给予一个示例):

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

XAML中的DataGrid列定义应如下所示:

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

另一种方法是将DataGrid的AutoGenerateColumns属性设置为true,并省略XAML中的列定义。但这样就无法对网格进行同样多的控制。

bakd9h0s

bakd9h0s2#

如果您想考虑使用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.可观察集合:https://www.c-sharpcorner.com/UploadFile/e06010/observablecollection-in-wpf/
1.信息属性已更改:https://www.c-sharpcorner.com/article/use-inotifypropertychanged-interface-in-wpf-mvvm/

  1. I命令: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.数据上下文是视图模型
1.网格项源是我的ObservableCollection

  1. Button命令绑定到ViewModel中的AddSubjectCommand

输出示例

ozxc1zmp

ozxc1zmp3#

**1.**必须使用类中的相应名称指定Binding名称。

<DataGrid>

    <DataGrid.Columns>
        <DataGridTextColumn Header="Subject" Binding="{Binding Subject}"/>
        <DataGridTextColumn Header="Weekly" Binding="{Binding Weekly}"/>
    </DataGrid.Columns>

</DataGrid>

**2.**声明类如下:

public class subjectsTable
{
    private string _subject;
    public string Subject
    {
        get{ return _subject; }
        set{ _subject = value; }
    }

    private string _weekly;
    public string Weekly
    {
        get{ return _weekly; }
        set{ _weekly = value; }
    }
}

警告:如果没有getter和setter,它将无法工作。

**3.**并添加如下行

var subjects = new ObservableCollection<subjectsTable>();
grid_scrap.ItemsSource = CollectionViewSource.GetDefaultView(subjects);

subjects.Add(new subjectsTable()
{
    Subject = "Computer Science",
    Weekly = "No"
});

相关问题