我正在尝试在具有两列的DataGrid上显示DataTable。
当我更新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
方法如果有人知道如何使数据可见,请帮助我。谢谢。
这是我添加两个主题之后发生的事情:
答案 0 :(得分:2)
您需要为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中的列定义。但是,那么您就没有对网格的太多控制。
答案 1 :(得分:1)
如果要考虑使用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>
请参阅以下内容:
示例输出