Hi, Following to the workaroud (flag IsSearchAsync) provided (https://feedback.telerik.com/Project/154/Feedback/Details/245938-fix-radgridview-having-groups-filters-sort-descriptors-and-search-query-in-t), we discovered two issues : 1) the behavior of the grid is changed while using IsSearchAsync as true or false (see 2018-08-01_1849_DragDrop_behavior_with_IsSearchAsync.swf video attached). When set to true, the line found by the searchbox is automatically reselected. When the flag is set to false, it's not the case. 2) while playing with drag&drop, after some time the grid became unstable (see 2018-08-01_1847_-_dragdrop_issue_with_IsAsyncSearch.swf video attached). You can see that at the beginning, the D&D works fine. At 0:20 I can't select any line, and when I try to D&D, it drops always the same customer. At 0:40 you can see that even the SearchBox is broken and the progressbar is looping forever
Use attached to reproduce. Workaround: Set the TableHeaderHeight again after loading the layout.
To reproduce: please refer to the attached sample project and gif file Workaround: GridViewSpreadExport spreadExporter = new GridViewSpreadExport(this.radGridView1); spreadExporter.ExportFormat = SpreadExportFormat.Pdf; spreadExporter.ExportVisualSettings = true; SpreadExportRenderer exportRenderer = new SpreadExportRenderer(); spreadExporter.RunExport(exportFile, exportRenderer); Process.Start(exportFile);
To reproduce: run the attached project and toggle the checkbox in the header cell of the child template. Workaround: use a custom GridCheckBoxHeaderCellElement public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); this.radGridView1.CreateCell += radGridView1_CreateCell; DataTable dt = new DataTable(); dt.Columns.Add("CategoryId", typeof(int)); dt.Columns.Add("CategoryName", typeof(string)); dt.Columns.Add("ParentCategoryId", typeof(int)); dt.Rows.Add(1, "Category1", 0); dt.Rows.Add(2, "Category2", 0); dt.Rows.Add(3, "Category3", 0); Random rand = new Random(); for (int i = 4; i < 20; i++) { dt.Rows.Add(i, "Category" + i, rand.Next(1, 4)); } this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "CategoryId", "ParentCategoryId"); this.radGridView1.DataSource = dt; this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; GridViewTemplate childTemplate = CreateChildTemplate(); GridViewRelation relation = new GridViewRelation( this.radGridView1.MasterTemplate, childTemplate); relation.ChildColumnNames.Add("CategoryId"); relation.ParentColumnNames.Add("CategoryId"); this.radGridView1.Relations.Add(relation); } private void radGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e) { if (e.CellType == typeof(GridCheckBoxHeaderCellElement)) { e.CellElement = new CustomGridCheckBoxHeaderCellElement(e.Column, e.Row); } } private GridViewTemplate CreateChildTemplate() { GridViewTemplate childTemplate = new GridViewTemplate(); childTemplate.AutoGenerateColumns = false; this.radGridView1.Templates.Add(childTemplate); GridViewDecimalColumn decColumn = new GridViewDecimalColumn { Name = "CategoryId", HeaderText = "CategoryId Id", FieldName = "CategoryId", IsVisible = false, MinWidth = 100 }; childTemplate.Columns.Add(decColumn); GridViewTextBoxColumn tbxColumn = new GridViewTextBoxColumn { Name = "RightName", HeaderText = "Right Name", FieldName = "RGT_NAME", ReadOnly = true, MinWidth = 100 }; childTemplate.Columns.Add(tbxColumn); GridViewCheckBoxColumn chkxColumn = new GridViewCheckBoxColumn { Name = "Checkbox", EnableHeaderCheckBox = true, FieldName = "HasAccess", }; childTemplate.Columns.Add(chkxColumn); childTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; return childTemplate; } public class CustomGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement { public CustomGridCheckBoxHeaderCellElement(GridViewColumn column, GridRowElement row) : base(column, row) { } public bool SuspendProcessingToggleStateChanged { get { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("suspendProcessingToggleStateChanged", BindingFlags.NonPublic | BindingFlags.Instance); return (bool)fi.GetValue(this); } set { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("suspendProcessingToggleStateChanged", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(this, value); } } public bool ShouldCheckDataRows { get { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("shouldCheckDataRows", BindingFlags.NonPublic | BindingFlags.Instance); return (bool)fi.GetValue(this); } set { FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("shouldCheckDataRows", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(this, value); } } protected override void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args) { if (SuspendProcessingToggleStateChanged) { return; } if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference) { this.MasterTemplate.BeginUpdate(); } else { this.TableElement.BeginUpdate(); } object valueState = DBNull.Value; if (args.ToggleState == ToggleState.On) { valueState = true; } else if (args.ToggleState == ToggleState.Off) { valueState = false; } else if (args.ToggleState == ToggleState.Indeterminate) { valueState = null; } RaiseToggleStateEvent(); if (!ShouldCheckDataRows) { if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference) { this.MasterTemplate.EndUpdate(true, new DataViewChangedEventArgs(ViewChangedAction.DataChanged)); } return; } this.GridViewElement.EditorManager.EndEdit(); this.TableElement.BeginUpdate(); this.MasterTemplate.MasterViewInfo.TableSearchRow.SuspendSearch(); List<GridViewRowInfo> list = GetRowsToIterateOver(); foreach (GridViewRowInfo rowInfo in list) { GridViewGroupRowInfo groupRow = rowInfo as GridViewGroupRowInfo; if (groupRow != null) { this.CheckAllCheckBoxInChildRows(groupRow, valueState); } else { rowInfo.Cells[this.ColumnIndex].Value = valueState; } } this.MasterTemplate.MasterViewInfo.TableSearchRow.ResumeSearch(); this.TableElement.EndUpdate(false); if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference) { this.MasterTemplate.EndUpdate(true, new DataViewChangedEventArgs(ViewChangedAction.DataChanged)); } else { this.TableElement.EndUpdate(false); } this.TableElement.Update(GridUINotifyAction.DataChanged); } private void CheckAllCheckBoxInChildRows(GridViewGroupRowInfo row, object state) { List<GridViewRowInfo> list = new List<GridViewRowInfo>(); foreach (GridViewRowInfo rowInfo in row.ChildRows) { list.Add(rowInfo); } foreach (GridViewRowInfo rowInfo in list) { GridViewGroupRowInfo groupInfo = rowInfo as GridViewGroupRowInfo; if (groupInfo != null) { this.CheckAllCheckBoxInChildRows(groupInfo, state); } else { rowInfo.Cells[this.ColumnIndex].Value = state; } } } private List<GridViewRowInfo> GetRowsToIterateOver() { if (this.ViewTemplate != null && this.ViewTemplate.IsSelfReference) { PrintGridTraverser traverser = new PrintGridTraverser(this.ViewInfo); List<GridViewRowInfo> result = new List<GridViewRowInfo>(); while (traverser.MoveNext()) { if (traverser.Current is GridViewDataRowInfo) { result.Add(traverser.Current); } } return result; } return new List<GridViewRowInfo>(this.ViewInfo.Rows); } } }
Hello,
In our Environment it's not possible to assign a GroupComparer to another GridView template then MasterTemplate. The GroupComparer property is always null after assignment.
It's possible to assign our custom comparer to the MasterTemplate and it will be triggered, but not in another template then MasterTemplate.
Best regards.
Tassilo Koller | Dipl. Informatiker (FH) | IT-Softwareentwicklung
[T] +49 (0)8233 381 383
[E] Tassilo.Koller@forum-media.com | [W] www.forum-verlag.com
FORUM MEDIA GROUP GMBH| Mandichostraße 18 | 86504 Merching | [T] +49 (0)8233 381-0 | [F] + 49 (0)8233 381-222 | [W] www.forum-media.com| Sitz der Gesellschaft: Merching | Register: AG Augsburg HRB 11537 | Geschäftsführer: Magdalena Balanicka, Norbert Bietsch, Roland Hradek, Mihaela Mravlje | Beirat: Ronald Herkert (Vorsitzender)
Elektronische Rechnungen bitte an folgende Adresse senden: invoice@forum-media.com
Steps to reproduce:
This happens after calling RunExport.
I attached a gif and a sample project.
June 19, 2019
I have implemented this and it is exactly what I want and need, Thank you!
However I thought I might point out that when you tab out it doesn't implement the search, only when you press enter.
And when you press the X to clear the search it clears the text box but not the search. the count of found and the highlighted finds remain
In my gridview need support of different heights of rows. I solved it with the autosize property.
But now I have a side action that the header row and filter row also react to the autosize property.
Attached you can see this behaviour...
Here my code:
Grid.MasterView.TableFilteringRow.MinHeight = 40
Grid.AutoSizeRows = True
Is there a chance to separate data rows from filter and header row?
Regards,
Dimitri
To reproduce:
- Set the AutoSize to true
- Add GroupDescriptor
- An InvalidOperationException is thrown
To reproduce: Sub New() InitializeComponent() Dim dt1 As New DataTable dt1.Columns.Add("Id", GetType(Integer)) dt1.Columns.Add("Name", GetType(String)) For index = 1 To 20 dt1.Rows.Add(index, "Parent" & index) Next Me.RadGridView1.MasterTemplate.DataSource = dt1 Me.RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill Dim dt2 As New DataTable dt2.Columns.Add("Id", GetType(Integer)) dt2.Columns.Add("Name", GetType(String)) dt2.Columns.Add("ParentId", GetType(Integer)) Dim dt3 As New DataTable dt3.Columns.Add("Id", GetType(Integer)) dt3.Columns.Add("Name", GetType(String)) dt3.Columns.Add("ParentId", GetType(Integer)) For index = 1 To 20 If index Mod 2 = 0 Then dt2.Rows.Add(index, "Child1." & index, index) If index Mod 4 = 0 Then dt3.Rows.Add(index, "Child2." & index, index) End If ElseIf index Mod 3 = 0 Then dt3.Rows.Add(index, "Child2." & index, index) Else dt3.Rows.Add(index, "Child2." & index, index) End If Next Dim template As New GridViewTemplate() template.DataSource = dt2 template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill RadGridView1.MasterTemplate.Templates.Add(template) Dim relation As New GridViewRelation(RadGridView1.MasterTemplate) relation.ChildTemplate = template relation.RelationName = "FirstChild" relation.ParentColumnNames.Add("Id") relation.ChildColumnNames.Add("ParentId") RadGridView1.Relations.Add(relation) Dim template2 As New GridViewTemplate() template2.DataSource = dt3 template2.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill RadGridView1.MasterTemplate.Templates.Add(template2) Dim relation2 As New GridViewRelation(RadGridView1.MasterTemplate) relation2.ChildTemplate = template2 relation2.RelationName = "SecondChild" relation2.ParentColumnNames.Add("Id") relation2.ChildColumnNames.Add("ParentId") RadGridView1.Relations.Add(relation2) AddHandler Me.RadGridView1.ChildViewExpanding, AddressOf ChildViewExpanding End Sub Private Sub RadGridView1_ViewCellFormatting(sender As Object, e As Telerik.WinControls.UI.CellFormattingEventArgs) _ Handles RadGridView1.ViewCellFormatting Dim cell As GridDetailViewCellElement = TryCast(e.CellElement, GridDetailViewCellElement) Dim expanderCell As GridGroupExpanderCellElement = TryCast(e.CellElement, GridGroupExpanderCellElement) If expanderCell IsNot Nothing AndAlso TypeOf e.CellElement.RowElement Is GridDataRowElement Then Dim hierarchyRow As GridViewHierarchyRowInfo = DirectCast(expanderCell.RowInfo, GridViewHierarchyRowInfo) If Not IsExpandable(hierarchyRow) Then expanderCell.Expander.Visibility = Telerik.WinControls.ElementVisibility.Hidden Else expanderCell.Expander.Visibility = Telerik.WinControls.ElementVisibility.Visible End If ElseIf cell IsNot Nothing Then Dim hierarchyRow As GridViewHierarchyRowInfo = DirectCast(DirectCast(cell.RowInfo, GridViewDetailsRowInfo).Owner, _ GridViewHierarchyRowInfo) For i As Integer = 0 To cell.PageViewElement.Items.Count - 1 Dim item As RadPageViewItem = cell.PageViewElement.Items(i) Dim viewInfo As GridViewInfo = hierarchyRow.Views(i) item.Text = "Child Template " & i If viewInfo.ChildRows.Count = 0 Then If i = 0 AndAlso i < cell.PageViewElement.Items.Count - 1 Then cell.PageViewElement.Items(i + 1).IsSelected = True End If item.Visibility = Telerik.WinControls.ElementVisibility.Hidden Else item.Visibility = Telerik.WinControls.ElementVisibility.Visible End If Next End If End Sub Private Function IsExpandable(hierarchyRow As GridViewHierarchyRowInfo) As Boolean For Each view As GridViewInfo In hierarchyRow.Views If view.ChildRows.Count > 0 Then Return True End If Next Return False End Function Workaround: AddHandler Me.RadGridView1.ChildViewExpanding, AddressOf RadGridView1_ChildViewExpanding AddHandler Me.RadGridView1.MouseDown, AddressOf RadGridView_MouseDown Private Sub RadGridView1_ChildViewExpanding(sender As Object, e As ChildViewExpandingEventArgs) If lastClicked IsNot Nothing AndAlso e.ParentRow.Equals(lastClicked) Then e.Cancel = False Else e.Cancel = True End If End Sub Dim lastClicked As GridViewRowInfo Private Sub RadGridView_MouseDown(sender As Object, e As MouseEventArgs) Dim expander As GridExpanderItem = TryCast(Me.RadGridView1.ElementTree.GetElementAtPoint(e.Location), GridExpanderItem) If expander IsNot Nothing Then lastClicked = DirectCast(expander.Parent, GridGroupExpanderCellElement).RowInfo End If End Sub
To reproduce: - Add a checkbox column and hide some of the cells. - Change some values and then click on empty cell. - Exception occurs in OnMouseDownLeft method (GridRowBeahvior class) Workaround: Hide the checkbox only.
To reproduce: 1. Add a RadMultiColumnComboBox and populate it with data. 2. Set the DropDownStyle property of the control to DropDownList 3. Set the EditorControl.AllowSearchRow and the AutoSizeDropDownToBestFit properties to true . 4. When you open the drop down and try to use the search row (e.g. clicking over the arrow buttons), the drop down is closed. Workaround: public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public RadForm1() { InitializeComponent(); this.radMultiColumnComboBox1.EditorControl.AllowSearchRow = true; this.radMultiColumnComboBox1.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDownList; this.radMultiColumnComboBox1.DropDownClosing += RadMultiColumnComboBox1_DropDownClosing; } private void RadMultiColumnComboBox1_DropDownClosing(object sender, RadPopupClosingEventArgs args) { Point position = this.radMultiColumnComboBox1.EditorControl.PointToClient(Cursor.Position); Telerik.WinControls.RadElement searchElement = this.radMultiColumnComboBox1.EditorControl.ElementTree.GetElementAtPoint(position); if (searchElement != null) { GridSearchCellElement parent = searchElement.FindAncestor<GridSearchCellElement>(); if (parent != null) { args.Cancel = true; } } } }
1. Create a new project and setup hierarchy 2. Add a large number of rows as child rows to the last row at first level 3. Run the project and try to expand the last row
- Create a new project containing RadGridView - Build hierarchy with large text data in cells - Set the AutoSizeRows property to true and AutoSizeColumnMode to Fill - Run the project, scroll down and try to click on a cell
I have the following logic for my View, which has a RadGridView control (add to form at design-time).
GUI is a lightweight view, Controller does the heavy lifting. That part is all good.
However setting the column name and column autosize stuff is a little more "over-complicated" than I'd wish to see. It all works though.
Would be nice to have a "GridViewTextBoxColumnAttribute" as per below, for properties on Custom datasource objects to achieve the same thing in a more concise way.
Or am I missing something and there is a much easier way to do what I want?
I have a number of datasource classes: MyObject, MyCar, MyDog, MyWhatever... that ALL have different property names and datatypes, but may or may-not have the same column name or MasterTemplate style.
Also BestFitColumns is a function of the MasterTemplate, would be nice if it were a property for consistency sake (call to internal function encapsulated in the Set etc), as from a Telerik user's perspective it's just an enum. Then it would be setable in the SmartTag window as well, as functions can't be assigned to.
public partial class RadForm1 : Telerik.WinControls.UI.RadForm, IView
{
public RadForm1)
{
InitializeComponent();
}
private void RadForm1_Load(object sender, EventArgs e)
{
var x = new Controller();
x.SetTemplate(this);
}
public Telerik.WinControls.UI.RadGridView RadGridView()
{
return this.radGridView1;
}
}
public class Controller
{
public void SetTemplate(IView view)
{
var View_RadGrid = view.RadGridView();
View_RadGrid.MasterTemplate.AutoGenerateColumns = false;
View_RadGrid.MasterTemplate.AutoGenerateHierarchy = false;
View_RadGrid.MasterTemplate.AllowColumnResize = false;
View_RadGrid.MasterTemplate.BestFitColumns(Telerik.WinControls.UI.BestFitColumnMode.AllCells);
var cols = new List<Telerik.WinControls.UI.GridViewDataColumn>()
{
new Telerik.WinControls.UI.GridViewTextBoxColumn("DisplayName1"),
new Telerik.WinControls.UI.GridViewTextBoxColumn("DisplayName2")
};
View_RadGrid.MasterTemplate.Columns.AddRange(cols.ToArray());
View_RadGrid.DataSource = new List<MyObject>()
{
new MyObject() { DisplayName1 = "1", DisplayName2 = "2" },
new MyObject() { DisplayName1 = "3", DisplayName2 = "4" }
};
}
private class MyObject
{
[GridViewTextBoxColumnAttribute("DisplayName1", BestFitColumn = Telerik.WinControls.UI.BestFitColumnMode.AllCells, AllowColumnResize = false)]
public string DisplayName1 { get; set; }
[GridViewTextBoxColumnAttribute("DisplayName2", BestFitColumn = Telerik.WinControls.UI.BestFitColumnMode.AllCells, AllowColumnResize = false)]
public string DisplayName2 { get; set; }
}
}
public interface IView
{
Telerik.WinControls.UI.RadGridView RadGridView();
}
[System.AttributeUsage(System.AttributeTargets.Property)]
public class GridViewTextBoxColumnAttribute : System.Attribute
{
private string FieldName;
public Telerik.WinControls.UI.BestFitColumnMode BestFitColumn;
public bool AllowColumnResize;
public GridViewTextBoxColumnAttribute(string fieldName)
{
this.FieldName = fieldName;
}
}