Hi all,
I've been stuck for a while trying to setup our WHDG. We have a dynamic, changing, dataset object coming back from our databases. This can have N relationships and tables in it. We must create the bands manually so that we can hide columns and format the display.
Note: If I set the grid to auto create the bands, it works fine but the display is no good for our needs.
However, if I try to create a band for each dataTable in the set then the 2nd level + band I create are not used.
Also, if I create the bands manually but leave AutoGenerateBands="True" then the 2nd level band has no formatting.
Is there some way I can view the auto generated bands in code? If so then maybe I could see what was wrong with my setup.
This is the function I used to setup the bands:
Protected Overrides Sub OnInit(ByVal e As EventArgs)
Dim i As Integer = 1 ' skip root band/table (this is already setup in the grid)
While i < Me.WHDG1.DataSource.Tables.Count
Dim band As New Infragistics.Web.UI.GridControls.Band
Dim table As New DataTable
table = Me.WHDG1.DataSource.Tables(i)
Me.WHDG1.Bands.Add(band)
band.DataMember = table.TableName
band.Key = table.TableName
band.DataKeyFields = "Autoid"
band.ShowHeader = False
band.AutoGenerateColumns = False
addDataField("Sel", "Sel", "20", False, "columnClassSel", table, band)
addDataField("Sel1", "Sel", "20", False, "columnClassSel", table, band)
addDataField("Sel2", "Sel", "20", False, "columnClassSel", table, band)
addDataField("Sel3", "Sel", "20", False, "columnClassSel", table, band)
addDataField("Sel4", "Sel", "20", False, "columnClassSel", table, band)
addDataField("Sel5", "Sel", "20", False, "columnClassSel", table, band)
addDataField("Sel6", "Sel", "20", False, "columnClassSel", table, band)
addDataField("display", "display", "", False, "", table, band)
addDataField("Available", "Available", "70", False, "columnClassAvailable", table, band)
addDataField("name", "name", "", True, "", table, band)
addDataField("parenttable", "parenttable", "", True, "", table, band)
addDataField("parentkey", "parentkey", "", True, "", table, band)
addDataField("childtable", "childtable", "", True, "", table, band)
addDataField("level", "level", "", True, "", table, band)
addDataField("filter", "filter", "", True, "", table, band)
addDataField("incex", "incex", "", True, "", table, band)
addDataField("tbl", "tbl", "", True, "", table, band)
addDataField("bandkey", "bandkey", "", True, "", table, band)
i = i + 1
End While
Private Sub addDataField(ByVal fieldName As String, ByVal key As String, ByVal width As String, ByVal hidden As Boolean, ByVal cssClass As String, ByRef table As DataTable, ByRef band As Infragistics.Web.UI.GridControls.Band)
If table.Columns.Contains(fieldName) Then
Dim dataField As Infragistics.Web.UI.GridControls.BoundDataField = New Infragistics.Web.UI.GridControls.BoundDataField
dataField.DataFieldName = fieldName
dataField.Key = fieldName
dataField.Hidden = hidden
dataField.CssClass = cssClass
If Not width = "" Then
dataField.Width = width
End If
band.Columns.Add(dataField)
End Sub
I am having similar issues. There are about a dozen different ways to bind the grid and I've tried them all twice. It seems that no matter what I do to format anything with the grid prior to binding is completely ignored. If I set autogeneratecolumns=false, then the grid is blank. I've tried the ThreeLevelsonManualLoad example, creating my webhierarchicaldatasource inline and the code behind, binding to a relational dataset....all of them will create the grid with a parent/child band as expected, but if I try to set column width or change a caption prior to binding, its ignored. We have the exact same code in the webdatagrid and it works correctly. Is this a bug with the webhierarchicalgrid?
Okay, I've got a little further with this now (thanks to trial and error, not thanks to any kind of Infragistics "support")
The WHDG will only happily use the bands you supply it if their layout and setup if perfect. This is why it's not displaying anything if you set it's AutoGenerateBands / Columns to "False"
The thing that caught me out with the bands was that they are hierarchical in nature. So say you have a grid with 3 levels:
Level 0 you do not make a band for, you set this up as the Columns of the grid itself
Level 1 you create a band for
Level 2 you create a band and insert it into the band collection of Level 1, not into the collection of bands for the WHDG itself.
A good way to troubleshoot the band setup is to set the grid to auto gen your bands and remove any code you have to make bands yourself. The handle a grid event, such as "OnUnload" and stop the debugger there. Have a look at the Bands collection it's autogenerated and make sure your manual band creation code matches this. I made a recusive function to do this:
(ignore code sketchyness plz)
Private Function populateBand(ByRef parentBand As Infragistics.Web.UI.GridControls.Band, ByVal i As Integer)
If i < Me.UltraWebGrid1.DataSource.Tables.Count Then
table = Me.UltraWebGrid1.DataSource.Tables(i)
band.DataKeyFields = "name"
' check if this is a band
Try
Dim str1 As String = table.Rows(0).Item(table.Columns.IndexOf("bandkey"))
Dim str2 As String = "x"
If Not String.Compare(str1, str2) = 0 Then
Catch ex As Exception
End Try
parentBand.Bands.Add(band)
' Revusivly add bands into this band
populateBand(band, i)
End Function
Hello,
I'm looking into this scenario.
I will update you soon.
Thanks.
I think a lot of the trouble with mapping the WHDG control would go away if there was a decent level of reporting coming back from the grid component on what it's unhappy about. It's very rare to get any kind of error from the grid, it just silently fails or ignores bands, etc.
If we could catch a .Error event or switch the grid into debug mode, so it complains about everything that isn't right (bands not being used, incorrect dataKeyFields, etc) then things would be a lot easier to setup in these more complex scenarios.
I thought it might be helpful if I sent my example. This does not work for me, but is similar to the VB example above. I wanted to have more control over the formatting of my columns before loading, so I moved my webhierarchicaldatasource to the code behind. I used the VB example as a model, but mine is C#. The grid does display with both the parent and details; however, it seems to ignore everything in my FOR loop where I am defining the datafields. You can see in my attached example that on the parent, I set the header text to "Test" and I also changed a couple of column widths just before binding. Neither works as expected. Any ideas?
Hello guys,
If I understand well your issue is that you are not able to style the child band when Mnaual Load on demand is used. The code below shows how can be implemented completely independently Manula Load On Demand and in the same time you are able to style the child band. Actually you have access to the columns even though they are generated on fly :
The gird aspx definition is as follows:
<ig:WebHierarchicalDataGrid ID="whdg1" runat="server" AutoGenerateColumns="false" AutoGenerateBands="false" InitialExpandDepth="0" InitialDataBindDepth="0" Height="450px" Width="862px" DataKeyFields="ID" OnRowIslandsPopulating="whdg1_RowIslandsPopulating" OnInitializeRow="whdg1_InitializeRow"> <ExpandCollapseAnimation SlideOpenDirection="Auto" SlideOpenDuration="300" SlideCloseDirection="Auto" SlideCloseDuration="300" /> <Columns> <ig:BoundDataField DataFieldName="ID" Key="ID" Header-Text="ID" /> <ig:BoundDataField DataFieldName="Fname" Key="Fname" Header-Text="Firs Name" Width="230px" /> <ig:BoundDataField DataFieldName="Sname" Key="Sname" Header-Text="Second Name" Width="150px" /> </Columns> </ig:WebHierarchicalDataGrid>
Implementation in code - behind is :
public partial class _Default : System.Web.UI.Page { #region Page protected override void OnInit(EventArgs e) { base.OnInit(e); this.whdg1.DataSource = GetPersons(); } protected void Page_Load(object sender, EventArgs e) { } #endregion #region Grid Events protected void whdg1_InitializeRow(object sender, RowEventArgs e) { if(isChild == false) ((ContainerGridRecord)e.Row).IsEmptyParent = true; } protected void whdg1_RowIslandsPopulating(object sender, Infragistics.Web.UI.GridControls.ContainerRowCancelEventArgs e) { e.Cancel = true; ContainerGrid child = new ContainerGrid(); child.InitializeRow += new InitializeRowEventHandler(child_InitializeRow); e.Row.RowIslands.Add(child); child.DataSource = GetAddresses(); child.DataBind(); } #endregion #region Child grid events bool isChild = false; void child_InitializeRow(object sender, RowEventArgs e) { e.Row.Items[0].Column.Header.Text = "This is the changed Add"; isChild = true; } #endregion #region Entities public class Person { public int _addressID; public int ID { get; set; } public string Fname { get; set; } public string Sname { get; set; } public int Addresses { get { return _addressID; } } } public class Address { public int ID { get; set; } public string Street { get; set; } public string City { get; set; } } #endregion #region Data private List<Person> GetPersons() { List<Person> list = new List<Person>(); list.Add( new Person() { ID = 1, Fname = "Rado", Sname = "Minchev",_addressID=1 }); list.Add( new Person() { ID = 2, Fname = "Vlado", Sname = "Zagorski", _addressID = 1 }); list.Add( new Person() { ID = 3, Fname = "Alex", Sname = "Fidanov", _addressID = 1 }); list.Add( new Person() { ID = 4, Fname = "Ivan", Sname = "Simeonov", _addressID = 2 }); list.Add( new Person() { ID = 5, Fname = "Anton", Sname = "Staikov", _addressID = 2 }); list.Add( new Person() { ID = 6, Fname = "Dimi", Sname = "Gineva", _addressID = 2 }); list.Add( new Person() { ID = 7, Fname = "Danko", Sname = "Valkov", _addressID = 2 }); list.Add( new Person() { ID = 8, Fname = "Cveti", Sname = "Georgieva", _addressID = 2 }); return list; } private List<Address> GetAddresses() { List<Address> list = new List<Address>(); list.Add( new Address() { ID = 1, City = "Windsor",
Street = "Corporate Park 50 Millstone Road" }); list.Add( new Address() { ID = 2, City = "Sofia", Street = "110 B, Simeonovsko Shosse Office Floor II" }); return list; } #endregion }
Hope this helps.
How would you create the following columns through the code-behind class?
<ig:BoundDataField DataFieldName="ID" Key="ID" Header-Text="ID" /> <ig:BoundDataField DataFieldName="Fname" Key="Fname" Header-Text="First Name" Width="230px" /> <ig:BoundDataField DataFieldName="Sname" Key="Sname" Header-Text="Second Name" Width="150px" />
I've tried to add the following to your sample:
private void AddBandColumn(IBand band, string dataField, string caption, bool hidden) //, AllowUpdate updatable) { BoundDataField column = new BoundDataField(true); column.DataFieldName = dataField; column.Key = dataField; column.Hidden = hidden; column.Header.Text = caption; band.Columns.Add(column); }
private void CreateColumns() { this.whdg1.Bands.Clear(); this.whdg1.Columns.Clear();
this.whdg1.DataKeyFields = "ID";
AddBandColumn(this.whdg1, "ID", "ID", false); AddBandColumn(this.whdg1, "Fname", "First Name", false); AddBandColumn(this.whdg1, "Sname", "Second Name", false);
//Second Level - Child Band band = new Band(); AddBandColumn(band, "ID", "ID", false); AddBandColumn(band, "City", "City", false); AddBandColumn(band, "Street", "Street", false); this.whdg1.GridView.Bands.Add(band); }
I even tried adding the parent columns to this.whdg1.GridView.Columns, but did not work.
Thanks