次の方法で共有


IDataSource and the SimpleSpreadsheetControl example in the ASP.NET docs

I was looking over the ASP.NET 2.0 server control documentation for writing databound controls and grabbed the sample code for the CompositeDataBoundControl server control base class to examine how to use the base class.  I configured it to bind to a SqlDataSource control.  It didn't work so I took a closer look at the code.  The databinding code happens in this method:

         protected override void RenderContents(HtmlTextWriter writer)
        {

            if (Data != null)
            {
                if (Data is System.Data.Common.DbDataRecord)
                {
                    DbDataRecord temp = (DbDataRecord)Data;
                    for (int i = 0; i < temp.FieldCount; ++i)
                    {
                        writer.Write("<TD>");
                        writer.Write(temp.GetValue(i).ToString());
                        writer.Write("</TD>");
                    }
                }
                else
                    writer.Write("<TD>" + Data.ToString() + "</TD>");
            }

            else
                writer.Write("<TD>This is a test</TD>");
        }

The code checks for a DbDataRecord but the type that is passed in when databound to an IDataSource based control is a DataRowView object not a DbDataRecord object so instead of rendering the data it renders the ToString() value for System.Data.DataRowView.  To remidie this issue, I modified the above method to also check if the object is of type DataRowView:

protected override void RenderContents(HtmlTextWriter writer)
    {
      if (Data != null)
      {
        if (Data is System.Data.Common.DbDataRecord)
        {
          DbDataRecord temp = (DbDataRecord)Data;
          for (int i = 0; i < temp.FieldCount; ++i)
          {
            writer.Write("<TD>");
            writer.Write(temp.GetValue(i).ToString());
            writer.Write("</TD>");
          }
        }
        else if (Data is System.Data.DataRowView)
        {
          DataRow temp = ((DataRowView)data).Row;

          for (int i = 0; i < temp.Table.Columns.Count; ++i)
          {
            writer.Write("<TD>");
            writer.Write(temp[i].ToString());
            writer.Write("</TD>");
          }
        }
        else
          writer.Write("<TD>" + Data.ToString() + "</TD>");
      }

      else
        writer.Write("<TD>This is a test</TD>");
    }

The sample now correctly binds to a SqlDataSource control.  I looked for a more elegant way to handle this than simply testing for the type but I didn't find a common base class I could use for both scenarios.  Maybe I'm too sleepy so if anyone out there sees a more streamlined way to do this feel free to comment below:-)

Comments