我正在使用DataGrids,但我正在努力绑定我的数据,因为列数会根据必须显示的信息而有所不同。
所以,我试图做的是创建和对象,其中包含我在某些时候需要的所有列和行,并将此对象绑定到ItemsSource
属性。由于我在WindowsForms中使用过DataGridViews,因此我想到了这样的事情:
DataTable myTable = new DataTable();
DataColumn col01 = new DataColumn("col 01");
myTable.Columns.Add(col01);
DataColumn col02 = new DataColumn("col 02");
myTable.Columns.Add(col02);
DataRow row = myTable.NewRow();
row[0] = "data01";
row[1] = "data02";
myTable.Rows.Add(row);
row = myTable.NewRow();
row[0] = "data01";
row[1] = "data02";
myTable.Rows.Add(row);
但我还没有找到在WPF中做同样事情的方法,因为我需要一些列为DataGridComboBoxColumns。
其实我在这个网站上看过很多关于它的帖子,但没有一个对我有帮助。我真的迷路了。
有人能帮帮我吗?我只需要能够创建一个可能包含DataGridTextColumns或`DataGridComboBoxColumns等的表,以便将这个最终对象绑定到DataGrid的ItemsSource属性。
希望有人可以帮助我。
答案 0 :(得分:4)
好的,让我试着举一个类似于你需要的例子
我们假设我们使用这个类:
public class MyObject
{
public int MyID;
public string MyString;
public ICommand MyCommand;
}
我们愿意显示列出该ID的DataGrid
,并将Button
作为第二列,其中包含属性MyString
作为内容,点击该列后会启动ICommand
MyCommand
,无论你想要什么,都会在新窗口中打开。
以下是您在View端应具备的内容:
<DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding MyID}" />
<DataGridTemplateColumn Header="Buttons">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding MyString}" Command="{Binding MyCommand}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
这将显示DataGrid
将IEnumerable<MyObject>
中的所有内容命名为“MyList”,并显示之前定义的两列。
现在,如果您需要定义命令。
首先,我建议您阅读this introductory link to MVVM并参加RelayCommand
课程(这是我们将用于您的问题)
因此,在ViewModel
中,定义MyList
的那个,下面是您应该如何定义一些有用的对象:
public ObservableCollection<MyObject> MyList { get; set; }
// blah blah blah
public void InitializeMyList()
{
MyList = new ObservableCollection<MyObject>();
for (int i = 0; i < 5; i++)
{
MyList.Add(InitializeMyObject(i));
}
}
public MyObject InitializeMyObject(int i)
{
MyObject theObject = new MyObject();
theObject.MyID = i;
theObject.MyString = "The object " + i;
theObject.MyCommand = new RelayCommand(param =< this.ShowWindow(i));
return theObject
}
private void ShowWindow(int i)
{
// Just as an exammple, here I just show a MessageBox
MessageBox.Show("You clicked on object " + i + "!!!");
}
答案 1 :(得分:2)
绑定到自定义对象的ObservableCollection的简单示例。向自定义对象添加更多属性,以匹配您希望行的外观。
using System.Collections.ObjectModel;
public MyClass
{
public ObservableCollection<MyObject> myList { get; set; }
public MyClass()
{
this.DataContext = this;
myList = new ObservableCollection<MyObject>();
myList.Add(new MyObject() { MyProperty = "foo", MyBool = false };
myList.Add(new MyObject() { MyProperty = "bar", MyBool = true };
}
}
public MyObject
{
public string MyProperty { get; set; }
// I believe will result in checkbox in the grid
public bool MyBool { get; set; }
//...as many properties as you want
}
使用xaml
<DataGrid ItemsSource= "{Binding myList}" />
可能是一些小的语法错误,我完全在SO窗口中写道。
答案 2 :(得分:-1)
我是WPF的新手,并使用Damascus的示例来学习List与datagrid的绑定。但是当我使用他的答案时,我发现我的数据网格将填充正确的行数,但不会填充MyObject类中的任何属性。我做了一些搜索然后偶然发现了我必须做的事情。
我必须封装MyObject类属性才能显示它们。将它们公之于众是不够的。
在:
public class MyObject
{
public int MyID;
public string MyString;
public ICommand MyCommand;
}
后:
public class MyObject
{
private int _myID;
public int MyID
{
get { return _myID; }
set { _myID = value; }
}
private string _myString;
public string MyString
{
get { return _myString; }
set { _myString = value; }
}
private ICommand _myCommand;
public ICommand MyCommand
{
get { return _myCommand; }
set { _myCommand = value; }
}
}
感谢大马士革的一个很好的例子,感谢Dante提出了一个很好的问题。我不知道这是否是由于您的帖子后版本发生了变化,但希望这会帮助其他像我这样的WPF新手。