将列表的内容数据绑定到数据网格
Posted
技术标签:
【中文标题】将列表的内容数据绑定到数据网格【英文标题】:Databinding the contents of a list to a datagrid 【发布时间】:2021-07-12 04:44:31 【问题描述】:我最近制作了一个由预先存在的表中的行组成的列表,并想尝试将该列表数据绑定到数据网格。然而,它只显示已定义的列名。有谁知道为什么这个绑定不起作用?
public class ViewModel1 : ViewModelBase, INotifyPropertyChanged
public List<Table1> AllDatainTable get; set;
private void SetInitialSettings()
AllDatainTable = new List<Table1>();
public List<Table1> GetAllDatainTable()
List<Table1> ret = new List<Table1>();
Table entity;
SqlDataAdapter da;
DataTable dt = new DataTable();
da = new SqlDataAdapter("SELECT * FROM Testdatabase.dbo.Table1", "Data Source=.;Initial Catalog=TestDatabase;Integrated Security=true");
da.Fill(dt);
foreach (DataRow dr in dt.Rows)
entity = new Testdatarow();
entity.ID = Convert.ToInt32(dr["ID"]);
entity.Name = dr["Name"].ToString();
ret.Add(entity);
return ret;
还有xaml
<DataGrid Grid.Row="1" Grid.RowSpan="6" x:Name="ContDatagrid" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="Binding AllDatainTable, Mode=OneWay,UpdateSourceTrigger=PropertyChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="Binding ID" Width="SizeToHeader" />
<DataGridTextColumn Header="Name" Binding="Binding Name" Width="SizeToHeader"/>
</DataGrid.Columns>
</DataGrid>
还有数据模型本身
public class Table1 : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private int _ID;
public int ID
get return _ID;
set
_ID = value;
RaisePropertyChanged("ID");
private string _Name;
public string Name
get return _Name;
set
_Name = value;
RaisePropertyChanged("Name");
private void RaisePropertyChanged(string property)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
最后是它在一些早期测试中使用的连接字符串
<connectionStrings>
<add name="ConnectionToDb" connectionString="Data Source=.;Initial Catalog=Testdatabase;Integrated Security=true" providerName="System.Data.SqlClient" />
</connectionStrings>
【问题讨论】:
你真的打电话给GetAllDatainTable()
吗?
需要额外的行或列?如果是列,则替换AutoGenerateColumns="True"
。
你设置了窗口的数据上下文了吗?例如,您可以在 xaml 中执行此操作:<Window.DataContext><local:ViewModel/></Window.DataContext>
【参考方案1】:
您错误地声明了属性集合的类型。 必须有一个可观察的集合(具有 INotifyCollectionChanged 实现)或一个 BindingList。
public class ViewModel1 : ViewModelBase, INotifyPropertyChanged
public ObservableCollection<Table1> AllDatainTable get;
= new ObservableCollection<Table1>();
public ViewModel1() => Update();
public void Update()
AllDatainTable.Clear();
foreach (var item in GetAllDatainTable)
AllDatainTable.Add(item);
public IReadOnlyList<Table1> GetAllDatainTable()
List<Table1> ret = new List<Table1>();
Table entity;
SqlDataAdapter da;
DataTable dt = new DataTable();
da = new SqlDataAdapter("SELECT * FROM Testdatabase.dbo.Table1", "Data Source=.;Initial Catalog=TestDatabase;Integrated Security=true");
da.Fill(dt);
foreach (DataRow dr in dt.Rows)
entity = new Testdatarow();
entity.ID = Convert.ToInt32(dr["ID"]);
entity.Name = dr["Name"].ToString();
ret.Add(entity);
return ret.AsReadOnly();
从您的代码中并不清楚您如何将此 ViewModel 设置为 Window 的 DataContext,以及如何调用数据更新方法。 因此,错误可能不仅出现在您显示的代码中。
【讨论】:
它不必是可观察的或绑定列表,只需将数据显示为只读。 @Crowcoder,如果列表是在 VM 构造函数中初始化的(即在创建绑定之前),那么您是对的。但是从 TC 代码来看,它在创建绑定后更改了集合。在这种情况下,您需要将属性中的集合实例完全替换为引发 PropertyChanged。或者它必须是一个可观察的集合。集合的元素是否可变与它无关。 我明白了,我对 WPF 比较陌生,因此执行另一个模型需要知道的方法的视图模型的概念对我来说仍然很陌生。在我的 .cs 文件中调用此方法的最佳方法是什么?在理想情况下,我希望在应用程序打开时填充数据网格。数据上下文已设置,如果我绑定到 .cs 中的一个完全空的列表,Visual Studio 会让我知道它没有返回值,因此模型正在通信 为您的 ViewModel 代码添加一个默认构造函数:public ViewModel1() => Update();
.
啊啊啊我搞定了,非常感谢!【参考方案2】:
试试这个
foreach (DataRow dr in dt.Rows)
ContDatagrid.Items.Add(dr);
【讨论】:
WPF DataGrid 没有 Items 属性,这不会遵循 MVVM 模式,看起来 OP 至少正在尝试。 @Crowcoder,你说的不对。 DataGrid 派生自 ItemsControl 并继承 Items 属性。但我同意你的观点,建议的代码非常糟糕。 你是对的我不对。编辑你的问题,我会带走 dv以上是关于将列表的内容数据绑定到数据网格的主要内容,如果未能解决你的问题,请参考以下文章
将对象列表数据绑定到 WinForms DataGridView,但不显示某些公共属性