[Mono-bugs] [Bug 74718][Nor] New - Data Bound Control inherited from Calendar does not render Day on Days with Data Bound items
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Sun, 24 Apr 2005 18:57:41 -0400 (EDT)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by joe_audette@yahoo.com.
http://bugzilla.ximian.com/show_bug.cgi?id=74718
--- shadow/74718 2005-04-24 18:57:41.000000000 -0400
+++ shadow/74718.tmp.22678 2005-04-24 18:57:41.000000000 -0400
@@ -0,0 +1,470 @@
+Bug#: 74718
+Product: Mono: Tools
+Version: 1.1
+OS: SUSE 9.2
+OS Details:
+Status: NEW
+Resolution:
+Severity:
+Priority: Normal
+Component: XSP
+AssignedTo: gonzalo@ximian.com
+ReportedBy: joe_audette@yahoo.com
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: Data Bound Control inherited from Calendar does not render Day on Days with Data Bound items
+
+Please fill in this template when reporting a bug, unless you know what
+you are doing.
+
+Description of Problem:
+I am trying to use a Data bound control that inherits from the
+System.Web.UI.WebControls.Calendar and INamingContainer. It works as
+expected on Windows but under mono the Day number is not rendering on days
+with data bound items. The Day number should be clickable to select the
+day. I am attaching a page with inline code and 2 classes that need to be
+compiled into DataCalendar.dll. Please tell me if you see something I can
+do to make it work in both places by changing my code.
+
+I am running Suse 9.2 with mono 1.1.7 r43477 from svn
+I am using mod_mono with Apache
+
+
+Steps to reproduce the problem:
+1. Compile the 2 classes DataCalendar and DataCalendarItem into
+DataCalendar.dll
+2. Try the attached page with the DataCalendar.dll accessible to it in the
+bin folder
+
+
+Actual Results:
+The Day number does not render in the calendar for days with data bound
+items.
+
+
+Expected Results:
+The Day number does render and is clickable for postback. This is the
+behaviour on Windows.
+
+
+How often does this happen?
+Every Time
+
+Additional Information:
+Page Code Starts here
+-----------------------
+<% @Register Namespace="DataControls" Assembly="DataCalendar"
+TagPrefix="dc" %>
+
+<% @Import Namespace="System.Data" %>
+
+<script language="cs" runat="server">
+
+ DataTable GetEventData()
+ {
+ DataTable dt = new DataTable();
+
+ dt.Columns.Add("EventTitle", typeof(String));
+ dt.Columns.Add("EventDay", typeof(DateTime));
+ dt.Columns.Add("Color", typeof(System.Drawing.Color));
+
+ DataRow r = dt.NewRow();
+ r["EventTitle"] = "Today's Event";
+ r["EventDay"] = System.DateTime.Today;
+ r["Color"] = System.Drawing.Color.Black;
+ dt.Rows.Add(r);
+
+ r = dt.NewRow();
+ r["EventTitle"] = "Tomorrow's Event";
+ r["EventDay"] = System.DateTime.Today.AddDays(1);
+ r["Color"] = System.Drawing.Color.Red;
+ dt.Rows.Add(r);
+
+ r = dt.NewRow();
+ r["EventTitle"] = "Tomorrow's Event #2";
+ r["EventDay"] = System.DateTime.Today.AddDays(1);
+ r["Color"] = System.Drawing.Color.Blue;
+ dt.Rows.Add(r);
+
+ r = dt.NewRow();
+ r["EventTitle"] = "Next Week's Event";
+ r["EventDay"] = System.DateTime.Today.AddDays(7);
+ r["Color"] = System.Drawing.Color.Green;
+ dt.Rows.Add(r);
+
+ return dt;
+ }
+
+
+ void Page_Load(Object o, EventArgs e)
+ {
+ cal1.DataSource = GetEventData();
+ }
+
+</script>
+
+
+<html>
+ <head><title>DataCalendar - Example 1</title></head>
+
+ <body>
+ <form runat="server">
+
+ <h3>Events DataTable constructed through code</h3>
+
+ <dc:DataCalendar id="cal1" runat="server" width="100%"
+DayField="EventDay"
+ BorderWidth="1" BorderStyle="None"
+CellPadding="0"
+ SelectorStyle-BorderWidth="0" Font-
+Name="Tahoma" SelectionMode="Day" ShowGridLines="True"
+ TitleStyle-CssClass="EventCalendarTitle"
+ TitleStyle-BorderWidth="0" DayHeaderStyle-
+CssClass="EventCalendarDayHeader" DayStyle-CssClass="EventCalendarDay"
+ WeekendDayStyle-
+CssClass="EventCalendarWeekendDay"
+ NextPrevStyle-
+CssClass="EventCalendarNextPrev" NextPrevStyle-ForeColor="White">
+ <DayWithEventsStyle ForeColor="#0033ff"
+Font-Bold="True" />
+ <CurrentDayStyle BackColor="WhiteSmoke"
+ForeColor="DarkGray" Font-Bold="True" />
+ <OtherMonthDayStyle
+BackColor="LightGray" ForeColor="DarkGray" />
+
+ <ItemTemplate>
+ <br />
+ <asp:Label id="lblTitle" runat="server"
+ Font-Size="8"
+ Font-Name="Arial"
+ Text='<%# Container.DataItem["EventTitle"] %
+>'
+ ForeColor='<%# Container.DataItem["Color"] %
+>'
+ />
+
+ </ItemTemplate>
+ </dc:DataCalendar>
+
+ </form>
+ </body>
+
+</html>
+
+---- End Page Code------
+
+//Compile the 2 classes below into DataCalendar.dll and put in the bin
+where the above page can find it.
+
+using System;
+using System.Web.UI;
+using System.Web.UI.WebControls;
+using System.Data;
+
+namespace DataControls
+{
+
+ /********************************************************
+ Class DataCalendarItem
+ - serves as the container for a single calendar entry,
+ allowing for databinding syntax like the following
+ to be used in the .aspx page:
+
+ <%# Container.DataItem("MyField") %>
+ ********************************************************/
+
+ public class DataCalendarItem : Control, INamingContainer
+ {
+
+ private DataRow _dataItem;
+
+ public DataCalendarItem(DataRow dr)
+ {
+ _dataItem = dr;
+ }
+
+ // because the source data will be a DataTable
+ // object, it makes sense for our DataItem
+ // property to return a DataRow object
+ // (i.e. a single item in the data source
+ // corresponds to a single row of data)
+ public DataRow DataItem
+ {
+ get {return _dataItem;}
+ set {_dataItem = value;}
+ }
+ }
+
+
+ /********************************************************
+ Class DataCalendar
+ - subclass of the ASP.NET Calendar control for
+ displaying events from a DataTable with support
+ for templates
+ ********************************************************/
+
+ public class DataCalendar : Calendar, INamingContainer
+ {
+
+ private object _dataSource;
+ private string _dataMember;
+ private string _dayField;
+ private ITemplate _itemTemplate;
+ private ITemplate _noEventsTemplate;
+ private TableItemStyle _dayWithEventsStyle = new
+TableItemStyle();
+ private TableItemStyle _currentDayStyle = new
+TableItemStyle();
+ private DataTable _dtSource;
+
+ // Support either a DataSet or DataTable object
+ // for the DataSource property
+ public object DataSource
+ {
+ get {return _dataSource;}
+ set
+ {
+ if (value is DataTable || value is
+DataSet)
+ _dataSource = value;
+ else
+ throw new Exception("The
+DataSource property of the DataCalendar control" +
+ " must be a DataTable or
+DataSet object");
+ }
+ }
+
+ // If a DataSet is supplied for DataSource,
+ // use this property to determine which
+ // DataTable within the DataSet should
+ // be used; if DataMember is not supplied,
+ // the first table in the DataSet will
+ // be used.
+ public string DataMember
+ {
+ get {return _dataMember;}
+ set {_dataMember = value;}
+ }
+
+
+ // Specify the name of the field within
+ // the source DataTable that contains
+ // a DateTime value for displaying in the
+ // calendar.
+ public string DayField
+ {
+ get {return _dayField;}
+ set {_dayField = value;}
+ }
+
+
+
+ public TableItemStyle DayWithEventsStyle
+ {
+ get {return _dayWithEventsStyle;}
+ set {_dayWithEventsStyle = value;}
+ }
+
+ public TableItemStyle CurrentDayStyle
+ {
+ get {return _currentDayStyle;}
+ set {_currentDayStyle = value;}
+ }
+
+ [TemplateContainer(typeof(DataCalendarItem))]
+ public ITemplate ItemTemplate
+ {
+ get {return _itemTemplate; }
+ set {_itemTemplate = value;}
+ }
+
+
+ [TemplateContainer(typeof(DataCalendarItem))]
+ public ITemplate NoEventsTemplate
+ {
+ get {return _noEventsTemplate; }
+ set {_noEventsTemplate = value;}
+ }
+
+ // [TemplateContainer(typeof
+(DataCalendarItem))]
+ // public ITemplate SelectedDayTemplate
+ // {
+ // get {return _selectedDayTemplate; }
+ // set {_selectedDayTemplate = value;}
+ // }
+
+
+ // Constructor
+ public DataCalendar() : base()
+ {
+ // since this control will be used for displaying
+ // events, set these properties as a default
+ this.SelectionMode = CalendarSelectionMode.None;
+ this.ShowGridLines = true;
+ }
+
+
+ private void SetupCalendarItem(TableCell cell, DataRow r,
+ITemplate t)
+ {
+ // given a calendar cell and a datarow, set up the
+ // templated item and resolve data binding syntax
+ // in the template
+ DataCalendarItem dti = new DataCalendarItem(r);
+ t.InstantiateIn(dti);
+ dti.DataBind();
+ cell.Controls.Add(dti);
+ }
+
+
+ protected override void OnDayRender(TableCell cell,
+CalendarDay day)
+ {
+ // _dtSource was already set by the Render
+method
+ if (_dtSource != null)
+ {
+
+ // We have the data source as a DataTable
+now;
+ // filter the records in the DataTable for
+the given day;
+ // force the date format to be MM/dd/yyyy
+ // to ensure compatibility with RowFilter
+ // date expression syntax (#date#).
+ // Also, take the possibility of time
+ // values into account by specifying
+ // a date range, to include the full day
+ DataView dv = new DataView(_dtSource);
+ dv.RowFilter = string.Format(
+ "{0} >= #{1}# and {0} < #{2}#",
+ this.DayField,
+ day.Date.ToString("MM/dd/yyyy"),
+ day.Date.AddDays(1).ToString
+("MM/dd/yyyy")
+ );
+
+
+ // are there events on this day?
+ if (dv.Count > 0)
+ {
+ // there are events on this day;
+if indicated,
+ // apply the DayWithEventsStyle to
+the table cell
+ if(day.Date == this.SelectedDate)
+ {
+ if (this._currentDayStyle !
+= null)
+ {
+
+ cell.ApplyStyle
+(this._currentDayStyle);
+ }
+
+ }
+ else
+ {
+ if
+(this.DayWithEventsStyle != null)
+ cell.ApplyStyle
+(this.DayWithEventsStyle);
+ }
+
+ // for each event on this day
+apply the
+ // ItemTemplate, with data bound
+to the item's row
+ // from the data source
+ if (this.ItemTemplate != null)
+ for (int i=0; i<dv.Count;
+i++)
+ {
+ SetupCalendarItem
+(cell, dv[i].Row, this.ItemTemplate);
+ }
+
+ }
+ else
+ {
+ // no events this day;
+ if(day.Date == this.SelectedDate)
+ {
+ if (this._currentDayStyle !
+= null)
+ {
+
+ cell.ApplyStyle
+(this._currentDayStyle);
+ }
+ }
+ else
+ {
+ if (this.NoEventsTemplate !
+= null)
+ SetupCalendarItem
+(cell, null, this.NoEventsTemplate);
+ }
+
+ }
+
+ }
+
+ // call the base render method too
+
+ // Joe Audette Note: Commenting this out does not
+change the behaviour under windows
+ // it still works as expected
+ base.OnDayRender(cell, day);
+
+ }
+
+ protected override void Render(HtmlTextWriter html)
+ {
+ _dtSource = null;
+
+ if (this.DataSource != null && this.DayField !=
+null)
+ {
+ // determine if the datasource is a
+DataSet or DataTable
+ if (this.DataSource is DataTable)
+ _dtSource = (DataTable)
+this.DataSource;
+ if (this.DataSource is DataSet)
+ {
+ DataSet ds = (DataSet)
+this.DataSource;
+ if (this.DataMember == null ||
+this.DataMember == "")
+ // if data member isn't
+supplied, default to the first table
+ _dtSource = ds.Tables[0];
+ else
+ // if data member is
+supplied, use it
+ _dtSource = ds.Tables
+[this.DataMember];
+ }
+ // throw an exception if there is a
+problem with the data source
+ if (_dtSource == null)
+ throw new Exception("Error finding
+the DataSource. Please check " +
+ " the DataSource and
+DataMember properties.");
+ }
+
+ // call the base Calendar's Render method
+ // allowing OnDayRender() to be executed
+ base.Render(html);
+ }
+
+
+ }
+
+}