我试图将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
是我的DataGrid,而subjectsTable
是我的DataTable。
我尝试过以下方法:
DataGrid.DataContext
而不是DataGrid.ItemSource
ItemSource = "{Binding Path=subjectsTable}"
DataGrid.Items.Add(dataRow)
将行添加为项目getter
的每个数据成员添加了setter
和Subject
方法如果有人知道如何使数据可见,那么请帮助我。谢谢。
以下是我添加两个主题后会发生的事情:
您需要为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中的列定义。但是你没有那么多的电网控制权。
如果你想考虑使用MVVM模式(https://intellitect.com/getting-started-model-view-viewmodel-mvvm-pattern-using-windows-presentation-framework-wpf/),这是一个基本的实现:
创建ViewModel:
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
}
你需要在这里理解的东西:
创建实现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>
请参阅以下内容:
样本输出