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;
}
}
How to reproduce: 1. Click DrugName Filter Icon. 2. Uncheck Combivent 3. OK 4. Click name Filter Icon 5. Uncheck Christoff 6. OK 7. Click DrugName Filter Icon 8. Uncheck Dilantin 9. OK In this scenario the grid should display only 2 rows but it displays 3. public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public List<Drug> DrugList { get; set; } public RadForm1() { InitializeComponent(); DrugList = new List<Drug>(); LoadDrugList(); radGridView1.DataSource = DrugList; radGridView1.EnableFiltering = true; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.MultiSelect = true; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); radGridView1.MasterTemplate.ShowFilteringRow = false; radGridView1.MasterTemplate.ShowHeaderCellButtons = true; } void LoadDrugList() { DrugList.Add(new Drug { Dosage = 25, DrugName = "Indocin", Name = "David"}); DrugList.Add(new Drug { Dosage = 50, DrugName = "Enebrel", Name = "Sam" }); DrugList.Add(new Drug { Dosage = 10, DrugName = "Hydralazine", Name = "Christoff"}); DrugList.Add(new Drug { Dosage = 21, DrugName = "Combivent", Name = "Janet"}); DrugList.Add(new Drug { Dosage = 100, DrugName = "Dilantin", Name = "Melanie"}); } } Workaround: use a custom filter popup public partial class RadForm1 : Telerik.WinControls.UI.RadForm { public List<Drug> DrugList { get; set; } public RadForm1() { InitializeComponent(); DrugList = new List<Drug>(); LoadDrugList(); radGridView1.DataSource = DrugList; radGridView1.EnableFiltering = true; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; this.radGridView1.MultiSelect = true; this.radGridView1.FilterPopupRequired += RadGridView1_FilterPopupRequired; } private void RadGridView1_FilterPopupRequired(object sender, FilterPopupRequiredEventArgs e) { e.FilterPopup = new CustomRadListFilterPopup(e.Column); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); radGridView1.MasterTemplate.ShowFilteringRow = false; radGridView1.MasterTemplate.ShowHeaderCellButtons = true; } void LoadDrugList() { DrugList.Add(new Drug { Dosage = 25, DrugName = "Indocin", Name = "David"}); DrugList.Add(new Drug { Dosage = 50, DrugName = "Enebrel", Name = "Sam" }); DrugList.Add(new Drug { Dosage = 10, DrugName = "Hydralazine", Name = "Christoff"}); DrugList.Add(new Drug { Dosage = 21, DrugName = "Combivent", Name = "Janet"}); DrugList.Add(new Drug { Dosage = 100, DrugName = "Dilantin", Name = "Melanie"}); } } public class CustomRadListFilterPopup : RadListFilterPopup { public CustomRadListFilterPopup(GridViewDataColumn dataColumn) : base(dataColumn) { } protected override void OnButtonOkClick(EventArgs e) { FilterMenuTreeItem treeMenuItem = this.Items.FirstOrDefault(i => i is FilterMenuTreeItem) as FilterMenuTreeItem; if (treeMenuItem == null) { base.OnButtonOkClick(e); } FilterMenuTreeElement listFilterElement = treeMenuItem.TreeElement; FilterOperator filterOperator = FilterOperator.IsEqualTo; switch (listFilterElement.SelectedMode) { case ListFilterSelectedMode.All: filterOperator = FilterOperator.None; break; case ListFilterSelectedMode.Null: filterOperator = FilterOperator.IsNull; break; case ListFilterSelectedMode.NotNull: filterOperator = FilterOperator.IsNotNull; break; } if (filterOperator != FilterOperator.IsEqualTo) { SetFilterOperator(filterOperator); this.ClosePopup(RadPopupCloseReason.CloseCalled); } else { CompositeFilterDescriptor compositeFilterDescriptor = new CompositeFilterDescriptor(); compositeFilterDescriptor.PropertyName = this.DataColumn.Name; RadListFilterDistinctValuesTable distinctValues = this.GetDistinctValuesTable(); string blanksKey = RadGridLocalizationProvider.CurrentProvider.GetLocalizedString(RadGridStringId.FilterMenuBlanks); bool blanks = listFilterElement.SelectedValues.Contains(blanksKey); compositeFilterDescriptor.LogicalOperator = FilterLogicalOperator.And; foreach (DictionaryEntry entry in distinctValues) { object key = entry.Key; if (string.IsNullOrEmpty(Convert.ToString(key))) { key = blanksKey; } if (this.DataColumn is GridViewDateTimeColumn || this.DataColumn.DataType == typeof(DateTime) || this.DataColumn.DataType == typeof(DateTime?)) { DateTime dateTime; if (DateTime.TryParse(key.ToString(), out dateTime)) { object dataKey; if (RadDataConverter.Instance.TryFormat(treeMenuItem.TreeElement.GroupedDateValues ? dateTime.Date : dateTime, typeof(string), this.DataColumn, out dataKey) == null) { key = dataKey; } } } if (!listFilterElement.SelectedValues.Contains(key)) { foreach (object value in (ArrayList)entry.Value) { FilterDescriptor descriptor; if (value == DBNull.Value) { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, null); } else if (this.DataColumn is GridViewDateTimeColumn || this.DataColumn.DataType == typeof(DateTime) || this.DataColumn.DataType == typeof(DateTime?)) { descriptor = new DateFilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, (DateTime?)value, false); } else { descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, value); } compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } } if (this.DataColumn.FilterDescriptor != null) { CompositeFilterDescriptor compositeFilter = this.DataColumn.FilterDescriptor as CompositeFilterDescriptor; if (compositeFilter != null) { foreach (var item in compositeFilter.FilterDescriptors) { if (listFilterElement.SelectedValues.Contains(item.Value)) { continue; } FilterDescriptor descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, item.Value); compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } else if(!listFilterElement.SelectedValues.Contains(this.DataColumn.FilterDescriptor.Value)) { FilterDescriptor descriptor = new FilterDescriptor(this.DataColumn.Name, FilterOperator.IsNotEqualTo, this.DataColumn.FilterDescriptor.Value); compositeFilterDescriptor.FilterDescriptors.Add(descriptor); } } this.FilterDescriptor = compositeFilterDescriptor; OnFilterConfirmed(); } } }
Workaround: private void radGridView1_ConditionalFormattingFormShown(object sender, EventArgs e) { ConditionalFormattingForm f = sender as ConditionalFormattingForm; if (f != null) { f.Width += 5; } }
To reproduce: Add a RadGridView and use the following code. When you expand the first row, the vertical scrollbar is not correct. Scrolling down changes its size. However, if you expand the last row, it takes few seconds to open. Second scenario: In addition of the following code, if you change the TableElement.PageViewMode to PageViewMode.ExplorerBar, expanding the first row takes few seconds to load the hierarchical data as well. public partial class Form1 : Form { public Form1() { InitializeComponent(); List<Item> items = new List<Item>(); List<SubItem> subItems = new List<SubItem>(); for (int i = 1; i <= 3; i++) { Item item = new Item(i, "Item" + i); for (int j = 1000; j <= 2010; j++) { subItems.Add(new SubItem(j, "SubItem" + j, i)); } items.Add(item); } this.radGridView1.DataSource = items; this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewTemplate template = new GridViewTemplate(); template.ReadOnly = true; template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; GridViewRelation relation = new GridViewRelation(this.radGridView1.MasterTemplate, template); relation.ParentColumnNames.Add("Id"); relation.ChildColumnNames.Add("ItemId"); this.radGridView1.MasterTemplate.Templates.Add(template); this.radGridView1.Relations.Add(relation); template.DataSource = subItems; } } public class Item { public int Id { get; set; } public string Title { get; set; } public Item(int id, string title) { this.Id = id; this.Title = title; } } public class SubItem { public int Id { get; set; } public int ItemId { get; set; } public string Name { get; set; } public SubItem(int id, string name, int itemId) { this.Id = id; this.ItemId = itemId; this.Name = name; } }
Hello,
I am having issues with DateTime editor in the grid. We have custom date/time format for our dates - "HH:mm:ss dd-MMM-yyyy" and the datetime editor is set to free form date time with this mask. When user typed a value in the editor it is passed to FreeFormDateTimeProvider.Validate method, which calls DateInput.ParseDate. DateTimeLexer splits this kind of values just fine, but obviously time related tokens comes first and then the date related tokens.
Unfortunately DateTimeParser.Parse method is made the way that it parse date at first and then time from the tokens list. In my case this means time value is parsed and the date value is dropped to default. Why didn't you check that if after ParseDate and ParseTime calls the date portion is null but there are still remaining tokens in the list, so you may call ParseDate one more time?
Do you have any suggestion how could I resolve this issue? Everything related to date time parsing is not extendable at all, starting from DateInput, most of the classes and methods are not public and even some public methods are not virtual. Can I have the Telerik free form date time typing capabilities in the editor but still have time part before date part?
Please run the attached sample project and try to expand a row. The following error occurs:
System.NullReferenceException was unhandled by user code
The function OnNotifyPropertyChanged(string propertyName) in RadGridView.cs does not call the base function of RadControl.
RadGridView.cs
protected override void OnNotifyPropertyChanged(string propertyName)
{
if (propertyName == "AutoSize")
{
if (!this.AutoSize)
{
this.RootElement.StretchHorizontally = true;
this.RootElement.StretchVertically = true;
}
else
{
this.RootElement.StretchHorizontally = false;
this.RootElement.StretchVertically = false;
}
}
}
RadControl.cs
/// <summary>
/// Raises the PropertyChanged event
/// </summary>
/// <param name="propertyName">The name of the property</param>
protected virtual void OnNotifyPropertyChanged(string propertyName)
{
this.OnNotifyPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnNotifyPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler1 =
(PropertyChangedEventHandler)this.Events[RadControl.PropertyChangedEventKey];
if (handler1 != null)
{
handler1(this, e);
}
}
Because of this i cannot do the following
RadGridView grid = new RadGridView();
grid.OnNotifyPropertyChanged("mypropertyname");
I currently work around this by doing the following
RadGridView grid = new RadGridView(); grid.OnNotifyPropertyChanged(new PropertyChangedEventArgs("mypropertyname"));
I need this functionality because i have a custom control which is derived from RadGridView and it has a custom property that requires databinding with INotifyPropertyChanged. I cannot implement this interface myself because the grid already does this.
I have checked this in both the 2018.1.220 and 2019.1.219 source.
Kind regards,
Edwin Dirkzwager
CIP Software
To reproduce:
Update the data source directly and check the OldItems array.
To reproduce: change the decimal separator to ",". Please refer to the attached sample project and follow the steps from the attached gif file. Workaround: change the CurrentCulture in your application in order to affect the decimal separator: Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
When UseCompatibleTextRendering property is set to false, the data cells overlaps the row header cells when horizontal scrolling is performed.
How can I enter the Value "" (empty string) in the traditional filter system (not Excel like filter).
The grid does not seem to accept an empty string as an argument to "Equals" through the UI.
Ideally I would like to extend the standard filter menu in traditional filtering (and the filter operator drop down in custom filtering dialog) to contain operators "Is Empty" "Is Not Empty" and "Is Null Or Empty", "Is Not Null And Not Empty"
Regards
Erwin
When you start typing in the search text box some long text, not all key strokes will be handled. Please refer to the attached gifs file illustrating the behavior in the previous version and the latest release.
Please refer to the attached sample project. Run the project and try typing "too long to type" in as your search.
To reproduce: use the following code snippet, save the layout and load it afterwards. You will notice that only the master and the first child template are successfully loaded. public Form1() { InitializeComponent(); DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); for (int i = 0; i < 5; i++) { dt.Rows.Add(i, "Parent" + i); } this.radGridView1.MasterTemplate.DataSource = dt; this.radGridView1.MasterTemplate.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill; //child level 1 GridViewTemplate template = new GridViewTemplate(); template.DataSource = GetData(5, 20, 0, 5); template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; radGridView1.MasterTemplate.Templates.Add(template); GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate); relation.ChildTemplate = template; relation.RelationName = "ParentChild"; relation.ParentColumnNames.Add("Id"); relation.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation); //child level 2 GridViewTemplate template2 = new GridViewTemplate(); template2.DataSource = GetData(20, 40, 5, 20); template2.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template.Templates.Add(template2); GridViewRelation relation2 = new GridViewRelation(template); relation2.ChildTemplate = template2; relation2.RelationName = "ParentChild"; relation2.ParentColumnNames.Add("Id"); relation2.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation2); //child level 3 GridViewTemplate template3 = new GridViewTemplate(); template3.DataSource = GetData(40, 100, 20, 40); template3.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template2.Templates.Add(template3); GridViewRelation relation3 = new GridViewRelation(template2); relation3.ChildTemplate = template3; relation3.RelationName = "ParentChild"; relation3.ParentColumnNames.Add("Id"); relation3.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation3); //child level 4 GridViewTemplate template4 = new GridViewTemplate(); template4.DataSource = GetData(100, 200, 40, 100); template4.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill; template3.Templates.Add(template4); GridViewRelation relation4 = new GridViewRelation(template3); relation4.ChildTemplate = template4; relation4.RelationName = "ParentChild"; relation4.ParentColumnNames.Add("Id"); relation4.ChildColumnNames.Add("ParentId"); radGridView1.Relations.Add(relation4); } private object GetData(int from, int to, int parentFrom, int parentTo) { DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("ParentId", typeof(int)); Random rand = new Random(); for (int i = from; i < to; i++) { dt.Rows.Add(i, "Child" + i, rand.Next(parentFrom, parentTo)); } return dt; } private void radButton1_Click(object sender, EventArgs e) { string s = "default.xml"; SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; dialog.Title = "Select a xml file"; if (dialog.ShowDialog() == DialogResult.OK) { s = dialog.FileName; } this.radGridView1.SaveLayout(s); } private void radButton2_Click(object sender, EventArgs e) { string s = "default.xml"; OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "xml files (*.xml)|*.xml|All files (*.*)|*.*"; dialog.Title = "Select a xml file"; if (dialog.ShowDialog() == DialogResult.OK) { s = dialog.FileName; } this.radGridView1.LoadLayout(s); } Workaround: grid templates for the inner levels are recreated after loading the layout. Their DataSource is null and the existing relations points to the old templates. Clear the relations and setup them again with the new child template instances.