XmlDataSource bound to XmlDocument
Read a XML-File from user and display it in GridView and DetailsView. Here the user can make modifications or add new entries. Then he can download the modified XML-file to his harddrive.
Sample XML:
<?xml version="1.0" encoding="utf-8"?>
<Mapping Version="2">
<MappingRelation Active="True" DirectionVar1ToVar2="True" Offset="0" Factor="1" Assignment="OnChange">
<ValueObject1 ItemType="symSystemVariable">
<BusType>-1</BusType>
<DatabaseName>HumiditySensor::p_Ambient</DatabaseName>
<Description />
<EnvVarName />
<FullName>HumiditySensor::p_Ambient</FullName>
<ID>1</ID>
<MessageName />
<Name>HumiditySensor::p_Ambient</Name>
<NeedsMessage>False</NeedsMessage>
<NetworkName />
<NodeName />
<SignalName />
<VariableType>2</VariableType>
</ValueObject1>
<ValueObject2 ItemType="symSignal">
<BusType>1</BusType>
<DatabaseName>CAN1</DatabaseName>
<Description />
<EnvVarName>ECAN 1</EnvVarName>
<FullName>CAN1::HumiditySensor::Luftfeuchte_HDT2800::_Ambient_Pressure</FullName>
<ID>0</ID>
<MessageName>Luftfeuchte_HDT2800</MessageName>
<Name>_Ambient_Pressure</Name>
<NeedsMessage>False</NeedsMessage>
<NetworkName>ECAN 1</NetworkName>
<NodeName>HumiditySensor</NodeName>
<SignalName>_Ambient_Pressure</SignalName>
<VariableType>0</VariableType>
</ValueObject2>
</MappingRelation>
<MappingRelation Active="True" DirectionVar1ToVar2="True" Offset="0" Factor="1" Assignment="OnChange">
<ValueObject1 ItemType="symSystemVariable">
<BusType>-1</BusType>
<DatabaseName>HumiditySensor::spec_Humidity</DatabaseName>
<Description />
<EnvVarName />
<FullName>HumiditySensor::spec_Humidity</FullName>
<ID>1</ID>
<MessageName />
<Name>HumiditySensor::spec_Humidity</Name>
<NeedsMessage>False</NeedsMessage>
<NetworkName />
<NodeName />
<SignalName />
<VariableType>2</VariableType>
</ValueObject1>
<ValueObject2 ItemType="symSignal">
<BusType>1</BusType>
<DatabaseName>CAN1</DatabaseName>
<Description />
<EnvVarName>ECAN 1</EnvVarName>
<FullName>CAN1::HumiditySensor::Luftfeuchte_HDT2800::_Specific_Humidity</FullName>
<ID>0</ID>
<MessageName>Luftfeuchte_HDT2800</MessageName>
<Name>_Specific_Humidity</Name>
<NeedsMessage>False</NeedsMessage>
<NetworkName>ECAN 1</NetworkName>
<NodeName>HumiditySensor</NodeName>
<SignalName>_Specific_Humidity</SignalName>
<VariableType>0</VariableType>
</ValueObject2>
</MappingRelation>
</Mapping>
I read the provided XML document into a XmlDocument. This Xmldocument is bound to a XmlDataSource (id="id_DataSourceMP") which in turn is bound to a GridView (id="id_GridViewMP") and a DetailsView (id="id_DetailsViewMP") control. Inside this function I can read back the data from the XmlDataSource and can change for example the PageIndex of the DetailsView.
But in other functions (mp_rowSelected, id_MapButton_Click) this produces the error "Object reference not set to an instance of an object".
Here is the code behind:
using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Xml;
using System.Xml.XPath;
public partial class Default : System.Web.UI.Page
{
//-----------------------------------------------------------------------
//PageCallBacks
//-----------------------------------------------------------------------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//DataTable dt = new DataTable();
//Session["DataTable"] = dt;
//XmlDocument xmlMap = new XmlDocument();
//Session["Mapping"] = xmlMap;
//TreeNode sv_selectedNode = new TreeNode();
//TreeNode pv_selectedNode = new TreeNode();
}
}
//--------------------------------------------------------------------------------------
//Callback Functions
//--------------------------------------------------------------------------------------
protected void sv_loadXml(Object sender, EventArgs e)
{
}
protected void pv_loadXml(Object sender, EventArgs e)
{
}
protected void tree_nodechange(Object sender, EventArgs e)
{
}
protected void mp_loadXml(Object sender, EventArgs e)
{
//String myFile = Server.MapPath("~/data/HumiditySensor_Map.xml");
if (id_FileUploaderMP.HasFile)
{
Stream myStream = id_FileUploaderMP.FileContent;
StreamReader sr = new StreamReader(myStream);
XmlDocument myDoc = new XmlDocument();
myDoc.Load(sr);
if (myDoc.DocumentElement.Name != "Mapping")
{
id_writeOut.InnerText = "Laden fehlgeschlagen!";
return;
}
id_DataSourceMP.Data = myDoc.InnerXml;
id_DataSourceMP.DataBind();
// Test
id_writeOut.InnerText = id_DataSourceMP.Data;
id_GridViewMP.DataSourceID = "id_DataSourceMP";
id_GridViewMP.DataBind();
id_DetailsViewMP.DataSourceID = "id_DataSourceMP";
id_DetailsViewMP.DataBind();
// Test
id_DetailsViewMP.PageIndex = 4;
}
}
protected void mp_rowSelected(Object sender, EventArgs e)
{
//id_DetailsViewMP.PageIndex = 4;
id_writeOut.InnerText = id_DataSourceMP.Data;
}
protected void id_MapButton_Click(object sender, EventArgs e)
{
id_writeOut.InnerText = id_DataSourceMP.Data;
id_DetailsViewMP.PageIndex = 1;
}
//--------------------------------------------------------------------------------------
//Override Functions
//--------------------------------------------------------------------------------------
protected override void Render(HtmlTextWriter writer)
{
foreach (GridViewRow row in id_GridViewMP.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
row.Attributes["onmouseover"] = "this.style.cursor='pointer';this.style.textDecoration='underline';";
row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
row.ToolTip = "Click to select row";
row.Attributes["onclick"] = this.Page.ClientScript.GetPostBackClientHyperlink(this.id_GridViewMP, "Select$" + row.RowIndex, true);
}
}
base.Render(writer);
}
}
I'm pretty sure I have some think errors related to the DataBinding. Can someone please enlighten me as to where my failure is or suggest an alternative solution?
Thanks in advance for any help and please be gentle, it's my first post.
Eureka! I've got the solution.
I had to use the property "DataSource" instead of "DataSourceIP":
id_DataSourceMP.Data = myDoc.InnerXml;
id_DataSourceMP.DataBind();
id_GridViewMP.DataSource = id_DataSourceMP;
id_GridViewMP.DataBind();
id_DetailsViewMP.DataSource = id_DataSourceMP;
id_DetailsViewMP.DataBind();
A subsequent fault was that the DetailsView 'forgot' its data.. I somehow thought that databinding means a control or datasource is bound forever, like in marriage. Maybe with a ring somewhere...
Buut, you have to bind these things everytime you look at them, i.e. when the DetailsView should show another page. Something like this function:
private void bindDataXml()
{
XmlDocument doc_MP = (XmlDocument)Session["Mapping"];
id_DataSourceMP.Data = doc_MP.InnerXml;
id_DataSourceMP.DataBind();
id_Grid_ViewMP.DataSource = id_DataSourceMP;
id_Grid_ViewMP.DataBind();
id_DetailsViewMP.DataSource = id_DataSourceMP;
id_DetailsViewMP.DataBind();
}
Maybe someone else will find this helpful.