我想将WPF DataGrid的列绑定到Dictionary中的某些对象,如下所示:
绑定路径=对象[i]
其中Objects是我的对象字典,因此每个单元格都代表一个Object元素。我怎么能这样做?
我想我需要为我的单元格创建一个模板,我做了,但如何在模板中获取列绑定的结果?我知道默认情况下,DataGridCell的内容是一个TextBlock,它的Text属性是通过列绑定结果设置的,但如果该结果是一个对象,我想我必须创建一个ContentTemplate。我怎么做,因为我尝试的东西没有显示任何东西。
这是我试过的:
<Style x:Key="CellStyle" TargetType="{x:Type dg:DataGridCell}">
<Setter Property="Template"> ---it should realy be ContentTemplate?
<Setter.Value>
<ControlTemplate>
<controls:DataGridCellControl CurrentObject="{Binding }"/> -- I would expect to get the object like this for this column path : Path=Objects[i] but is not working
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
所以,为了让自己完全清楚,我想在我的DataGridCellControl的CurrentObject属性中获取当我在数据网格中设置列绑定时应该产生的当前对象,如Path = Objects [i]。
感谢您的任何建议,
约翰。
答案 0 :(得分:0)
试试这个:
<ListView x:Name="listViewUsers" SelectionMode="Single"
ItemsSource="{Binding ElementName=window1, Path=Users, Mode=TwoWay}" MouseDoubleClick="listViewUsers_MouseDoubleClick">
<ListView.View>
<GridView x:Name="gridViewUsers" AllowsColumnReorder="False">
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=IsAdministrator, Converter={StaticResource boolToImage}, ConverterParameter='Images/admin18.gif|Images/user18.gif'}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="User Name" DisplayMemberBinding="{Binding Path=UserName}" Width="140" />
<GridViewColumn Header="Full Name" DisplayMemberBinding="{Binding Path=FullName}" Width="140" />
<GridViewColumn Header="Phone Number" DisplayMemberBinding="{Binding Path=PhoneNumber}" Width="110" />
<GridViewColumn Header="Access Type" DisplayMemberBinding="{Binding Path=AccessType}" Width="110">
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Cursor="Hand" ToolTip="Delete User" Stretch="None" Source="Images/trash12.gif" MouseUp="DeleteUser" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
ItemsSource中的位置=“{Binding ElementName = window1,Path = Users,Mode = TwoWay}”
ElementName是XAML中窗口的名称(只需将x:Name =“window1”添加到Window标记中,与任何其他控件一样。
用户是一个List,应该与Dictionary
Mode = TwoWay意味着如果网格被修改,列表也会被修改,反之亦然(双向绑定)
修改强>
试试这个:
XAML:
<ListView x:Name="listViewTest" ItemsSource="{Binding}">
<ListView.View>
<GridView x:Name="gridViewTest">
</GridView>
</ListView.View>
</ListView>
C#:
public class TheClass
{
public int Col1, Col2, Col3;
public Dictionary<int, OtherColumns> otherColumns = new Dictionary<int,OtherColumns>();
}
public class OtherColumns
{
public string ColumnName;
public int Value;
}
在Window_Loaded:
下调用此方法private void PopulateListView()
{
TheClass c = new TheClass();
c.Col1 = 10;
c.Col2 = 20;
c.Col3 = 30;
c.otherColumns.Add(0, new OtherColumns() { ColumnName = "Col4", Value = 40 });
c.otherColumns.Add(1, new OtherColumns() { ColumnName = "Col5", Value = 50 });
c.otherColumns.Add(3, new OtherColumns() { ColumnName = "Col6", Value = 60 });
DataTable table = new DataTable();
// adding regular columns
table.Columns.Add("Col1", typeof(int));
table.Columns.Add("Col2", typeof(int));
table.Columns.Add("Col3", typeof(int));
// adding dynamic columns
foreach (KeyValuePair<int, OtherColumns> pair in c.otherColumns)
{
table.Columns.Add(pair.Value.ColumnName, typeof(int));
}
DataRow row = table.NewRow();
// adding regular column values to the DataTable
row["Col1"] = c.Col1;
row["Col2"] = c.Col2;
row["Col3"] = c.Col3;
// adding dynamic column values to the DataTable
foreach (KeyValuePair<int, OtherColumns> pair in c.otherColumns)
{
row[pair.Value.ColumnName] = pair.Value.Value;
}
table.Rows.Add(row);
// Start binding the table.
gridViewTest.Columns.Clear();
System.Windows.Controls.GridViewColumn gvc;
Binding binding;
foreach (DataColumn column in table.Columns)
{
gvc = new System.Windows.Controls.GridViewColumn();
binding = new System.Windows.Data.Binding();
binding.Path = new PropertyPath(column.ColumnName);
binding.Mode = BindingMode.OneWay;
gvc.Header = column.Caption;
gvc.DisplayMemberBinding = binding;
gridViewTest.Columns.Add(gvc);
}
listViewTest.DataContext = table;
}
我不是说这是最好的解决方案,但它可以提供帮助。让我知道。
答案 1 :(得分:0)
我创建了一些辅助类,因此我可以将DataGrid用作一种DataTable。换句话说,我想要DataGrid的格式化,排序和抛光外观,而不必事先预先制作一些类。我想要的主要原因是测试套件,我希望能够在运行时创建任意数量的列。这就是我得到的
public class DataRow
{
internal List<object> Items = new List<object>();
public object this[string value]
{
get { return Items[Convert.ToInt32(value)]; }
}
public string GetString(int index)
{
return Items[index].ToString();
}
public object GetObject(int index)
{
return Items[index];
}
public DataRow(params object[] values)
{
if (values == null || values.Length < 1)
throw new Exception("You must pass in some values");
Items.AddRange(values);
}
}
public class GridConstructor
{
public List<DataRow> Rows = new List<DataRow>();
private DataRow headers;
public GridConstructor(DataRow head)
{
headers = head;
}
public void BuildInto(DataGrid grid)
{
grid.AutoGenerateColumns = false;
grid.Columns.Clear();
int totalCols = 0;
Type headType = headers.GetType();
for (int i = 0; i < headers.Items.Count; i++)
{
grid.Columns.Add(GetCol(headers.GetString(i), String.Concat("[", i.ToString(),"]")));
totalCols++;
}
int finalWidth = totalCols * (int)grid.ColumnWidth.Value + 15;
grid.Width = finalWidth;
grid.ItemsSource = Rows;
}
private DataGridTextColumn GetCol(string header, string binding)
{
DataGridTextColumn col = new DataGridTextColumn();
col.IsReadOnly = true;
col.Header = header;
col.Binding = new Binding(binding);
return col;
}
public DataGrid Create(int colSize)
{
DataGrid grid = new DataGrid();
grid.ColumnWidth = colSize;
grid.CanUserAddRows = false;
grid.AlternationCount = 2;
BuildInto(grid);
return grid;
}
}
将它们放在一起,这是一个示例用途:
void SimpleTest_Loaded(object sender, RoutedEventArgs e)
{
DataRow headers = new DataRow("Level", "Weapon Type", "vs None", "vs Leather", "vs Studded", "vs Brigandine");
GridConstructor gridConstructor = new GridConstructor(headers);
var weaponType = "Slash";
for (int level = 1; level < 10; level++)
{
int damage = DiceCup.RollMulti(8, level);
int damCloth = damage - DiceCup.RollMulti(2, level);
int damLeather = damage - DiceCup.RollMulti(3, level);
int damStudded = damage - DiceCup.RollMulti(4, level);
int damBrigandine = damage - DiceCup.RollMulti(5, level);
DataRow row = new DataRow(level, weaponType, damage, damCloth, damLeather, damStudded, damBrigandine);
gridConstructor.Rows.Add(row);
}
//Create the grid.
var grid = gridConstructor.Create(100);
//Create a chart.
Chart chart = new Chart();
chart.Height = 200;
chart.LegendTitle = "Legend";
chart.Title = "Slash vs Armor Types";
chart.DataContext = gridConstructor.Rows;
//Create our series, or lines.
LineSeries slashVsNone = new LineSeries();
slashVsNone.Title = "vs None";
slashVsNone.DependentValueBinding = new Binding("[2]");
slashVsNone.IndependentValueBinding = new Binding("[0]");
slashVsNone.ItemsSource = gridConstructor.Rows;
chart.Series.Add(slashVsNone);
//Presentation is a stackpanel on the page.
presentation.Children.Add(grid);
presentation.Children.Add(chart);
}
输出:
alt text http://quiteabnormal.com/images/codeSample.jpg
请注意,网格着色来自页面上设置的通用样式。如果你使用GridConstructor.BuildInto()方法,你可以指定一个你自己在Blend中预先格式化的网格或者某些。
只有一件事,GridConstructor对列的初始设置做了一些假设。如果你愿意,你可以更改类以使其更具可定制性,但这是我需要的,所以我希望能够毫不费力地制作它。