The demo I started with is here. I put a break point in the task load routine and then looked at the hundreds of properties the datagrid had. I was able to reverse engineer some XAML that demonstrates how to set up the properties required to make the demo work with explicit band and field definitions.
Extract the sample code from the demo and replace the Infragistics references with your Infragistics version.
The XAML and code in MainWindow that comes with the demo looks like this.
<Window x:Class="DataGrid_LazyLoadChildren.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:igDp="http://infragistics.com/DataPresenter"
xmlns:local="clr-namespace:DataGrid_LazyLoadChildren"
Title="MainWindow" Height="350" Width="525">
<Grid>
<igDp:XamDataGrid x:Name="igDataGrid" >
</igDp:XamDataGrid>
</Grid>
</Window>
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows;
namespace DataGrid_LazyLoadChildren
{
public partial class MainWindow : Window
{
ObservableCollection<Order> orders;
public MainWindow()
{
InitializeComponent();
orders = new ObservableCollection<Order>()
{
new Order{ OrderID = 1, OrderName = "Order
1"},
new Order{ OrderID = 2, OrderName = "Order
2"}
};
igDataGrid.DataSource = orders;
}
}
public class Order : INotifyPropertyChanged
{
private int
_orderID;
public int OrderID
{
get { return
_orderID; }
set { _orderID = value; PropChanged("OrderID"); }
}
private string
_orderName;
public string
OrderName
{
get { return
_orderName; }
set { _orderName = value; PropChanged("OrderName"); }
}
private List<Task> _tasks = null;
public List<Task> Tasks
{
get
{
if (_tasks == null)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (ss, ee) =>
{
Thread.Sleep(500);
_tasks =
GetData(OrderID);
PropChanged("Tasks");
};
worker.RunWorkerAsync();
}
return _tasks;
}
}
public static List<Task> GetData(int orderID)
{
List<Task> data
= new List<Task>();
if (orderID == 1)
{
data.Add(new Task { TaskID = 1, TaskName = "Task
1" });
data.Add(new Task { TaskID = 2, TaskName = "Task
2" });
data.Add(new Task { TaskID = 3, TaskName = "Task
3" });
data.Add(new Task { TaskID = 4, TaskName = "Task
4" });
}
else
{
data.Add(new Task { TaskID = 21, TaskName = "Task
21" });
data.Add(new Task { TaskID = 22, TaskName = "Task
22" });
data.Add(new Task { TaskID = 23, TaskName = "Task
23" });
data.Add(new Task { TaskID = 24, TaskName = "Task
24" });
}
return data;
}
public event PropertyChangedEventHandler
PropertyChanged;
public void
PropChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
public class Task : INotifyPropertyChanged
{
private int _taskID;
public int TaskID
{
get { return _taskID;
}
set { _taskID = value;
PropChanged("TaskID"); }
}
private string
taskName;
public string TaskName
{
get { return
taskName; }
set { taskName = value; PropChanged("TaskName"); }
}
public event PropertyChangedEventHandler
PropertyChanged;
public void
PropChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
The resulting application looks like this.
As you see, the XamDataGrid is capable of figuring out how to display the data by looking at the enumerable property (tasks) of the order object and creating a child grid to display the tasks. This is great if you have compliant users, but mine want all sorts of extra stuff that requires explicit band (FieldLayout) and column (Field) definitions.
I figured out how the columns need to be defined to produce the same effect.
<Window x:Class="DataGrid_LazyLoadChildren.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:igDp="http://infragistics.com/DataPresenter"
xmlns:local="clr-namespace:DataGrid_LazyLoadChildren"
Title="MainWindow" Height="350" Width="525">
<Grid>
<igDp:XamDataGrid x:Name="igDataGrid"
GroupByAreaLocation="None" Theme="LunaSilver">
<igDp:XamDataGrid.FieldLayoutSettings>
<igDp:FieldLayoutSettings AutoGenerateFields="false"/>
</igDp:XamDataGrid.FieldLayoutSettings>
<igDp:XamDataGrid.FieldLayouts>
<igDp:FieldLayout Description="Orders" Key="Orders">
<igDp:FieldLayout.Fields>
<igDp:Field Label="Order
ID" Name="OrderID"/>
<igDp:Field Label="Order
Name" Name="OrderName"/>
<igDp:Field Name="Tasks"/>
</igDp:FieldLayout.Fields>
</igDp:FieldLayout>
<igDp:FieldLayout Description="Tasks" Key="Tasks" ParentFieldLayoutKey="Orders" ParentFieldName="Tasks">
<igDp:Field Label="Task ID" Name="TaskID"/>
<igDp:Field Label="Task Name" Name="TaskName"/>
</igDp:FieldLayout>
</igDp:XamDataGrid.FieldLayouts>
</igDp:XamDataGrid>
</Grid>
</Window>
There are several things to note.
- The invisible field in the first fieldlayout linked to the Tasks property of the Order. Because Tasks is enumerable, XamDataGrid understands it cannot be displayed. Without this field, we will not see an expander.
- In the second fieldlayout we reference the first fieldlayout by setting our ParentFieldLayoutKey to the first fieldlayout's key (Orders). This tells XamDataGrid which of our ancestors contains the data that will populate this fieldlayout.
- In the second fieldlayout we specify the field that contains the data we will display by setting ParentFieldName to the Name of the ancestor's field (Tasks).
- These two properties tell XamDataGrid that the Tasks property of our Orders ancestor will be our "DataSource".
This XAML produces pretty much the same application as the one that came with the demo except the column headers are better, but we are now in a position to provide some customization to our users. For example, let's add an child grid description.
Add a label to the Tasks field so it looks like this
<igDp:Field Label="Order's Tasks" Name="Tasks"/>
and add FieldSettings section below the FieldLayoutSettings like this.
<igDp:XamDataGrid.FieldSettings>
<igDp:FieldSettings ExpandableFieldRecordHeaderDisplayMode="AlwaysDisplayHeader"/>
</igDp:XamDataGrid.FieldSettings>
Run the application again and expand one of the rows.
No comments:
Post a Comment