User Profile & Activity

Robert Pehrson Member
Page
of 2

Unfortunately it is not straightforward to extract the entire configuration, as it's constructed in code with quite a few different options.  We have a workaround now and are not dependant on this bug being fixed. 

The problem seems to occur when the grid attempts to restore expanded/collapsed grouped rows from a very large dataset with the grid configured to use 'VirtualLoad'.  Changing the grid to use 'Paged' mode (where large data sets are broken down into pages of data) resolves the issue. 

The WebUI update is now picked up by Update Manager, and installing it has fixed the problem.

Thanks

Robert

I have the same problem.  When its DataSource is a DataView, a WebCombo takes all the rows from the underlying DataTable without applying the RowFilter property.  However, it does apply the Sort property.

Handy, your sample isn't the same, as it performs a new database Select to get a new dataset. In my case, I want to avoid accessing the database again, and so I create a DataView on an existing DataTable.

The attached example shows the problem.  The first combo correctly contains all three rows of the DataTable. The second combo "WebComboDV" has a DataView as its DataSource with a RowFilter that filters out all but one row.  However, the combo is populated with all three rows, ignoring the DataView's RowFilter property - but it does sort the rows according to the Sort property.

The following is code behind for the Programmatic WebCombo sample.

public partial class cs_WebCombo_Programmatic_worked_DataView : System.Web.UI.Page
{
    DataTable dt;
       
    protected void Page_Load(object sender, EventArgs e)
    {
        WebCombo combo = new WebCombo("WebCombo1");
        combo.Width = Unit.Pixel(200);
        combo.Height = Unit.Pixel(20);
        combo.UseDefaultStyle = true;
        combo.DataTextField = "ColA";
        combo.DataValueField = "Id";

        WebCombo comboDV = new WebCombo("WebComboDV");
        comboDV.Width = Unit.Pixel(200);
        comboDV.Height = Unit.Pixel(20);
        comboDV.UseDefaultStyle = true;
        comboDV.DataTextField = "ColA";
        comboDV.DataValueField = "Id";

        // Setup Events
        combo.InitializeDataSource += new DataSourceEventHandler(combo_InitializeDataSource);
        comboDV.InitializeDataSource += new DataSourceEventHandler(combo_InitializeDataSourceDV);

        //this.Controls.Add(combo);
        this.DivContainer.Controls.Add(combo);
        this.DivContainer.Controls.Add(comboDV);

        dt = new DataTable();
        dt.Columns.Add("Id");
        dt.Columns.Add("ColA");
        dt.Columns.Add("ColB");
        dt.Columns.Add("ColC");

        dt.Rows.Add(new object[] { 1, "cell1A", "cell1B", "cell1C" });
        dt.Rows.Add(new object[] { 2, "cell2A", "cell2B", "cell2C" });
        dt.Rows.Add(new object[] { 3, "cell3A", "cell3B", "cell3C" });
        dt.AcceptChanges();
    }

    protected void combo_InitializeDataSource(object sender, DataSourceEventArgs e)
    {
        e.DataSource = dt;
    }

    protected void combo_InitializeDataSourceDV(object sender, DataSourceEventArgs e)
    {
        DataView dv = new DataView(dt, "ColA='cell2A'", "ColB DESC", DataViewRowState.CurrentRows);
        e.DataSource = dv;
    }
}

 

Here is an outline of my workaround to show how a group value can be aggregated and included in formatted text in the group header. 

The process is initiated by the InitializeRow event:

    grid.InitializeRow += OnInitializeRow;

The event handler picks out the rows that are group headers.  In my application, there are nested groups, and the whole group hierarchy has to be processed to aggregate values; so my InitializeRow handler picks out the group headers at the top of the hierarchy:

private void OnInitializeRow(object sender, ISNet.WebUI.WebGrid.RowEventArgs e)
{
    WebGridRow row = e.Row;

    if (row.Type == RowType.GroupHeader)
    {
        if (row.Parent == null)
        {   
            // this group header row is at the top of the group hierarchy
            PopulateGroupHeader(row);
        }
    }

    e.ReturnValue = true;
}

The processing is done in a method that is called recursively for each level of the group hierarchy.

private void PopulateGroupHeader(WebGridRow row)
{
    WebGridGroup group = row.GetGroup();

    // Detect which group is being processed...
    string col = group.Column.DataMember; 

    if (col == "outerGroupColumn")
    {
        // For nested groups, process the child groups...
        foreach (WebGridRow childRow in row.Children)
        {
            PopulateGroupHeader(childRow);
        }
    }
    else if (col == "innerGroupColumn")
    {
        // Process each row in the inner group...
        foreach (WebGridRow leafRow in row.Children)
        {
            if (leafRow.DataRow != null)
            {
                DataRow r = ((DataRowView)leafRow.DataRow).Row;

                // Access the columns in this row to form aggregated data...
                object datavalue = r["ColumnName"];
            }
        }

        //Use the aggregated data in a formatted string and place in the group header...
        row.Cells[0].GroupRowInfoText = "formatted text";
    }

Hi Martin

Thanks for your confirmation that custom aggregate is not available in group headers. 

I do have a workaround.  Picking up each group header in an InitializeRow event handler, traversing its child rows to accumulate the aggregate result, and constructing the text using the result, I can then place the formatted text in the row's Cells[0].GroupInfoText. 

Regards

Robert

Hi Martin

The workaround is to address the cell after it's been created, either with SetItemData or by assigning to its Text property.  The following assigns to the Text property and then writes into the Style of one of the cells.  This just sets the BackColor, but I've been setting other properties including CssClass -

        childRows[10].Cells[0].Text = "PS1372";
        childRows[10].Cells[1].Text = "Computer Phobic AND Non-Phobic Individuals: Behavior Variations";
        childRows[10].Cells[2].Text = "Psychology";
        childRows[10].Cells[2].Style.BackColor = System.Drawing.Color.Yellow;
        childRows[10].Cells[3].Text = "14.69";

Regards

Robert

Thanks, Martin

It does work if I assign just the text to each cell, but that's doesn't get me any further than the original call on SetItemData to assign all texts at once.  My problem is that I need to set properties on individual cells as well as their text.  I have a workaround now, which is to assign the texts first (which presumably creates the cells), and then select individual cells by index -

gridRow.Cells[i].Style.CssClass += "classname";

Regards

Robert 

You're right, Riendy, it's the ChildExpanded property that I need - it works fine.  The help could be clearer about this; as I understand "expanded", child rows are shown when the parent is expanded and not when the parent is collapsed. So for the Expanded property "Gets or sets a value that indicates whether the row is expanded" should read "... whether the row's parent is expanded".  The ChildExpanded text is "Determines whether the Child Rows of current row is expanded" should read "... whether this row is expanded". 

Anyway, thanks for your help. 

Thanks for your explanation, Riendy.  This is in some code that I have inherited using the Name property of SelectedRow, but I'm sure I can manage without it and use just Text and Value.

Hi Riendy,

I thought my sample was attached as a file, but I see that in fact it's not - apologies!  Here it is.  This is the code behind for a page that includes PlaceHolder1.

using System;
using System.Data;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class cs_WebCombo_ResultBoxWorked : System.Web.UI.Page
{
    ISNet.WebUI.WebCombo.WebCombo WebCombo2;

    protected void Page_Load(object sender, EventArgs e)
    {
        WebCombo2 = new ISNet.WebUI.WebCombo.WebCombo();
        PlaceHolder1.Controls.Add(WebCombo2);

        WebCombo2.InitializeDataSource += OnInitializeDataSource;

        if (!IsPostBack)
        {
            WebCombo2.DataTextField = "FirstColumn";
            WebCombo2.DataValueField = "SecondColumn";
            WebCombo2.AllowAutoPostback = true;
            WebCombo2.AllowAutoDataCaching = true;
            WebCombo2.UseDefaultStyle = true;
        }

        var r = WebCombo2.SelectedRow; // this throws XmlException "Root element is missing" on the second drop-down
    }

    private void OnInitializeDataSource(object sender, ISNet.WebUI.WebCombo.DataSourceEventArgs eOriginal)
    {
        DataTable dt = new DataTable();
        dt.TableName = "TestData";
        dt.Columns.Add("FirstColumn", typeof(string));
        dt.Columns.Add("SecondColumn", typeof(string));

        dt.Rows.Add("one1", "one2");
        dt.Rows.Add("two1", "two2");

        eOriginal.DataSource = dt;
    }

}

All times are GMT -5. The time now is 11:36 PM.
Previous Next