Figure 2 Data Relation is Set Up private void Form1_Load(object sender, System.EventArgs e)
{
// Fetch the data
DataSet ds = LoadData();
// Set relations up
DataColumn dc1, dc2;
dc1 = ds.Tables["Employees"].Columns["employeeid"];
dc2 = ds.Tables["Orders"].Columns["employeeid"];
DataRelation rel = new DataRelation("EmployeesToOrders", dc1, dc2);
ds.Relations.Add(rel);
// Realize an AUTOMATIC master/detail schema
// with a child datagrid
// Configure the two grids
masterGrid.DataSource = ds;
masterGrid.DataMember = "Employees";
detailGrid.DataSource = ds;
detailGrid.DataMember = "Employees.EmployeesToOrders";
}
private DataSet LoadData()
{
DataSet ds = new DataSet();
SqlDataAdapter da = ConfigureDataAdapter();
da.Fill(ds);
return ds;
}
private SqlDataAdapter ConfigureDataAdapter()
{
// Set up the connection
String connString = "DATABASE=northwind;" +
"INTEGRATED SECURITY=sspi;" +
"SERVER=localhost;";
SqlConnection conn = new SqlConnection(connString);
// Define the commands to execute
String strCmd1 = "SELECT employeeid, lastname,
firstname FROM Employees";
String strCmd2 = "SELECT Employees.employeeid, " +
" Orders.OrderID, Orders.OrderDate, " +
" Sum([Order Details].UnitPrice * [Order Details].Quantity)
AS Total " +
"FROM Employees " +
"INNER JOIN Orders ON Employees.EmployeeID = Orders.EmployeeID
" +
"INNER JOIN [Order Details] ON Orders.OrderID =
[Order Details].OrderID " +
" WHERE (YEAR(Orders.OrderDate) = @nYear) " +
"GROUP BY Orders.orderid, Orders.OrderDate,
Employees.EmployeeID " +
"ORDER BY Employees.employeeid";
// Create the SELECT command
SqlCommand cmd = new SqlCommand(strCmd1 + ";" + strCmd2, conn);
SqlParameter p1 = new SqlParameter("@nYear", SqlDbType.Int);
p1.Value = 1998;
cmd.Parameters.Add(p1);
// Create the data adapter
SqlDataAdapter da = new SqlDataAdapter();
da.TableMappings.Add("Table", "Employees");
da.TableMappings.Add("Table1", "Orders");
da.SelectCommand = cmd;
return da;
}
Figure 6 DetailListView using System;
using System.Windows.Forms;
using System.Data;
using System.Text;
namespace AutoBindListView
{
/// Summary description for DetailListView.
public class DetailListView : ListView
{
public DetailListView()
{
View = View.Details;
FullRowSelect = true;
}
// DataMember Property
private String m_DataMember = "";
private String m_RelationName = "";
private String m_ParentTable = "";
public String DataMember
{
get {return m_DataMember;}
set {m_DataMember = value;
if (m_DataMember == "")
return;
char[] sep = {'.'};
Array a = m_DataMember.Split(sep);
m_ParentTable = a.GetValue(0).ToString();
m_RelationName = a.GetValue(1).ToString();
if (m_DataSource != null)
AutoBind();
}
}
// DataSource Property
private object m_DataSource = null;
public object DataSource
{
get {return m_DataSource;}
set {m_DataSource = value;
if (m_DataMember != "")
AutoBind();
}
}
/// Connects to the binding context to get the objects
/// connected to the specified data source and parent table.
/// Next, register to be invoked when the current selection
/// changes in that control. When this happens, refreshes its view
private void AutoBind()
{
CurrencyManager cm;
cm = (CurrencyManager) BindingContext[DataSource,
m_ParentTable];
cm.CurrentChanged += new EventHandler(CurrentChanged);
RefreshList(cm);
}
/// Invoked when the selection changes, refresh the list view
private void CurrentChanged(object sender, EventArgs e)
{
RefreshList((CurrencyManager) sender);
}
/// Refreshes the child view using the DataRelation to get to
/// the child rows of the selected row
private void RefreshList(CurrencyManager cm)
{
// Assuming it is bound to a DataTable/DataView
DataRowView drv;
drv = (DataRowView) cm.Current;
// Use the relation to extract the child rows
DataRow row = drv.Row;
DataRow [] rgChildRows = row.GetChildRows(m_RelationName);
// The listview is in Details view mode so add columns as
// needed
DataTable dt = rgChildRows[0].Table;
Columns.Clear();
foreach(DataColumn c in dt.Columns)
{
ColumnHeader ch = new ColumnHeader();
ch.Text = c.ColumnName;
ch.Width = 100;
ch.TextAlign = HorizontalAlignment.Left;
if (c.DataType == typeof(System.Int32) ||
c.DataType == typeof(Decimal))
ch.TextAlign = HorizontalAlignment.Right;
Columns.Add(ch);
}
// Populates the listview with the child rows
Items.Clear();
foreach(DataRow r in rgChildRows)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = r[0].ToString();
for(int i=1; i<dt.Columns.Count; i++)
lvi.SubItems.Add(r[i].ToString());
Items.Add(lvi);
}
}
}
}
Figure 7 Dynamically Adding Columns DataTable dt = rgChildRows[0].Table;
Columns.Clear();
foreach(DataColumn c in dt.Columns)
{
ColumnHeader ch = new ColumnHeader();
ch.Text = c.ColumnName;
ch.Width = 100;
ch.TextAlign = HorizontalAlignment.Left;
if (c.DataType == typeof(System.Int32) ||
c.DataType == typeof(Decimal))
ch.TextAlign = HorizontalAlignment.Right;
Columns.Add(ch);
}
Figure 9 Customizing the DataGrid's Style private void Form1_Load(object sender, System.EventArgs e)
{
// Fetch the data
DataSet ds = LoadData();
// Bind the master grid to data
masterGrid.DataSource = ds;
masterGrid.DataMember = "Employees";
// Make the grid display a subset of columns
//
// Step 1 - Create a table style and map it to the table name
// (case-sensitive)
DataGridTableStyle gridStyle = new DataGridTableStyle();
gridStyle.MappingName = "Employees";
gridStyle.BackColor = System.Drawing.Color.Ivory;
// Step 2 - Create column styles and map to column names
DataGridTextBoxColumn col1 = new DataGridTextBoxColumn();
col1.TextBox.Enabled = false;
col1.Alignment = HorizontalAlignment.Right;
col1.HeaderText = "ID";
col1.MappingName = "employeeid";
gridStyle.GridColumnStyles.Add(col1);
DataGridTextBoxColumn col2 = new DataGridTextBoxColumn();
col2.TextBox.Enabled = false;
col2.HeaderText = "Last Name";
col2.MappingName = "lastname";
gridStyle.GridColumnStyles.Add(col2);
DataGridTextBoxColumn col3 = new DataGridTextBoxColumn();
col3.TextBox.Enabled = false;
col3.HeaderText = "First Name";
col3.MappingName = "firstname";
gridStyle.GridColumnStyles.Add(col3);
// Step 3 - Connect grid and style. (Must be done here.)
masterGrid.TableStyles.Add(gridStyle);
// Configure the row viewer custom control
rowViewer.DataSource = ds;
rowViewer.DataMember = "Employees";
}
|