Desislava Yordanova
Team Member

ADD. RadGanttView - the user should be allowed to delete links from the graphical view by UI

Feature Request by Desislava Yordanova Status: Approved Comments: 1 Category: RadGanttView Scheduled for: Not Scheduled Last update: 2017-07-21T05:34:35 by Eddie Chu
0
Hristo Merdjanov
Team Member

ADD. RadRichTextEditor - implement font embedding mechanism for PDF export

Feature Request by Hristo Merdjanov Status: New Comments: 0 Category: RadRichTextEditor Scheduled for: Not Scheduled Last update: 2017-07-20T12:48:48 by Hristo Merdjanov
0
Desislava Yordanova
Team Member

FIX. RadScheduler - NoNullAllowedException is thrown when adding a new appointment although the entered data is valid

Please refer to the attached gif file and sample project.

Workaround: remove the database restrictions and validate the data in the edit dialog before submitting the new appointment data.
Bug Report by Desislava Yordanova Status: In Development Comments: 0 Attachments: 2 Category: RadScheduler Scheduled for: R3 2017 Last update: 2017-07-20T10:41:50 by Desislava Yordanova
0
Desislava Yordanova
Team Member

FIX. RadScheduler - appointments move while resizing

To reproduce: Use the following code snippet:

DateTime dt = DateTime.Now;
this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A1"));
this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A2"));

By default, when two appointments start at the same time, on the left side it is displayed the shorter appointment. Hence, if you start resizing an appointment it may jump to another location leaving the mouse in a wrong and inconsistent position. The attached gif illustartes the behavior.

Workaround:

public RadForm1()
{
InitializeComponent();

this.radScheduler1.ElementProvider = new MyElementProvider(this.radScheduler1);

DateTime dt = DateTime.Now;
this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A1"));
this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A2"));
}

private class AppointmentDateInfo : IComparable
{
public AppointmentElement appointment;
public DateTime date;
public bool isEnd;
private DateTimeComparer comparer;

public AppointmentDateInfo(AppointmentElement appointment, DateTime date, bool isEnd)
{
this.comparer = new DateTimeComparer(appointment.Scheduler);
this.appointment = appointment;
this.date = date;
this.isEnd = isEnd;
}

public int CompareTo(object obj)
{
AppointmentDateInfo other = obj as AppointmentDateInfo;
if (other == null)
{
return 1;
}

int res = date.CompareTo(other.date);
if (res == 0)
{
if (other.appointment != this.appointment)
{
res = other.isEnd.CompareTo(isEnd);
}
else
{
res = this.isEnd.CompareTo(other.isEnd);
}
}
if (appointment.Start.Equals(other.appointment.Start))
{
return res != 0 ? res : appointment.AppointmentSubject.CompareTo(other.appointment.AppointmentSubject);
}
return res != 0 ? res : comparer.Compare(appointment, other.appointment);
}
}

public class MyElementProvider : SchedulerElementProvider
{
public MyElementProvider(RadScheduler scheduler) : base(scheduler)
{
}

protected override T CreateElement<T>(SchedulerView view, object context)
{
if (typeof(T) == typeof(DayViewAppointmentsTable))
{
return new CustomDayViewAppointmentsTable(this.Scheduler, view, (DayViewAppointmentsArea)context)as T;
}

return base.CreateElement<T>(view, context);
}
}

public class CustomDayViewAppointmentsTable : DayViewAppointmentsTable
{
public CustomDayViewAppointmentsTable(RadScheduler scheduler, SchedulerView view, DayViewAppointmentsArea area) : base(scheduler, view, area)
{
}

private int FindLaneSpan(AppointmentElement appointment, Dictionary<AppointmentElement, int> appointmentLanes, int maxLanes)
{
int lane = appointmentLanes[appointment];
int span = maxLanes - lane;

int cellsPerHour = this.GetDayViewBase().GetNumberOfCellsPerHour();
int minutesPerSlot = 60 / cellsPerHour;

DateTime roundedAppStart = this.GetRulerRoundedDateTime(appointment.Start, false);
DateTime roundedAppEnd = this.GetRulerRoundedDateTime(appointment.End, true);

if (appointment.Start == appointment.End)
{
roundedAppEnd = roundedAppEnd.AddMinutes(minutesPerSlot);
}

foreach (KeyValuePair<AppointmentElement, int> item in appointmentLanes)
{
if (appointment == item.Key)
{
continue;
}

DateTime roundedItemStart = this.GetRulerRoundedDateTime(item.Key.Start, false);
DateTime roundedItemEnd = this.GetRulerRoundedDateTime(item.Key.End, true);

if (item.Key.Start == item.Key.End)
{
roundedItemEnd = roundedItemEnd.AddMinutes(minutesPerSlot);
}

if (roundedItemStart < roundedAppEnd && roundedItemEnd > roundedAppStart && item.Value > lane)
{
span = Math.Min(span, item.Value - lane);
}
}

return span;
}

private int FindFreeLane(List<AppointmentElement> overlappingAppointments, Dictionary<AppointmentElement, int> appointmentLanes)
{
List<int> indexes = new List<int>();

for (int i = 0; i < overlappingAppointments.Count; i++)
{
indexes.Add(appointmentLanes[overlappingAppointments[i]]);
}

indexes.Sort();

for (int i = 0; i < indexes.Count; i++)
{
if (i < indexes[i])
{
return i;
}
}

return overlappingAppointments.Count;
}

protected override void ArrangeAppointments(SizeF finalSize)
{
RectangleF containerRect = new RectangleF(PointF.Empty, finalSize);
List<AppointmentElement> appointmentsInLayout = new List<AppointmentElement>();

foreach (AppointmentElement element in this.AppointmentElements)
{
if (element.Visibility != ElementVisibility.Collapsed)
{
appointmentsInLayout.Add(element);
}
}

appointmentsInLayout.Sort(new DateTimeComparer(this.Scheduler));
Dictionary<AppointmentElement, object> arrangedAppointments = new Dictionary<AppointmentElement, object>();

foreach (AppointmentElement appointmentElement in appointmentsInLayout)
{
if (arrangedAppointments.ContainsKey(appointmentElement))
{
continue;
}

appointmentElement.RelatedAppointments.Sort(new DateTimeComparer(this.Scheduler));

List<AppointmentDateInfo> appointmentDates = new List<AppointmentDateInfo>();
List<AppointmentElement> overlappingAppointments = new List<AppointmentElement>();
Dictionary<AppointmentElement, int> appointmentLanes = new Dictionary<AppointmentElement, int>();

foreach (AppointmentElement relatedAppointment in appointmentElement.RelatedAppointments)
{
if (relatedAppointment.Visibility == ElementVisibility.Collapsed)
{
continue;
}

DateTime appStart = relatedAppointment.Start <= relatedAppointment.End ? relatedAppointment.Start : relatedAppointment.End;
DateTime appEnd = relatedAppointment.Start <= relatedAppointment.End ? relatedAppointment.End : relatedAppointment.Start;

if (!this.Scheduler.EnableExactTimeRendering)
{
if (appStart != appEnd)
{
appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appStart, false), false));
appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appEnd, true), true));
}
else
{
int cellsPerHour = this.GetDayViewBase().GetNumberOfCellsPerHour();
int minutesPerSlot = 60 / cellsPerHour;

appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appStart, false), false));
appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appEnd, true).AddMinutes(minutesPerSlot),
true));
}
}
else
{
appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, appStart, false));
appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, appEnd, true));
}
}

appointmentDates.Sort();
int maxLanesCount = 0;

for (int i = 0; i < appointmentDates.Count; i++)
{
if (!appointmentDates[i].isEnd)
{
int freeLane = FindFreeLane(overlappingAppointments, appointmentLanes);
appointmentLanes.Add(appointmentDates[i].appointment, freeLane);
overlappingAppointments.Add(appointmentDates[i].appointment);
maxLanesCount = Math.Max(maxLanesCount, freeLane + 1);
}
else
{
overlappingAppointments.Remove(appointmentDates[i].appointment);
}

if (overlappingAppointments.Count == 0)
{
foreach (KeyValuePair<AppointmentElement, int> item in appointmentLanes)
{
AppointmentElement appointment = item.Key;
int lane = item.Value;
DateTime rulerRoundStart = this.GetRulerRoundedDateTime(appointment.Start, false);
DateTime rulerRoundEnd = this.GetRulerRoundedDateTime(appointment.End, true);

if (appointment.Start == appointment.End)
{
int cellsPerHour = this.GetDayViewBase().GetNumberOfCellsPerHour();
int minutesPerSlot = 60 / cellsPerHour;

rulerRoundEnd = rulerRoundEnd.AddMinutes(minutesPerSlot);
}

PointF location = GetItemLocationInTable(appointment.Start, finalSize);

float dayWidth = this.Area.DayViewElement.GetColumnWidth(this.Area.DayViewElement.GetColumnForDate(rulerRoundStart), finalSize.Width);
int laneSpan = FindLaneSpan(appointment, appointmentLanes, maxLanesCount);

SizeF size = new SizeF(dayWidth / maxLanesCount * laneSpan, this.GetItemHeight(appointment.Start, appointment.End));
location.X += dayWidth / maxLanesCount * lane + this.Area.DayViewElement.AppointmentMargin.Left;
location.Y += this.Area.DayViewElement.AppointmentMargin.Top;
size.Width -= this.Area.DayViewElement.AppointmentMargin.Horizontal;

appointment.DesiredBounds = this.OnAppointmentLayout(appointment, new RectangleF(location, size), finalSize);
if (!arrangedAppointments.ContainsKey(appointment))
{
arrangedAppointments.Add(appointment, null);
}
}

appointmentLanes.Clear();
maxLanesCount = 0;
}
}

for (int i = 0; i < appointmentsInLayout.Count; i++)
{
AppointmentElement appointment = appointmentsInLayout[i];

if (appointment.Visibility != ElementVisibility.Visible)
continue;

RectangleF rectangle = appointment.DesiredBounds;

if (this.RightToLeft)
{
rectangle = LayoutUtils.RTLTranslateNonRelative(rectangle, containerRect);
}

appointment.Arrange(rectangle);
}
}
}
}

Bug Report by Desislava Yordanova Status: New Comments: 0 Attachments: 2 Category: RadScheduler Scheduled for: Not Scheduled Last update: 2017-07-20T10:14:14 by Desislava Yordanova
0
Desislava Yordanova
Team Member

FIX. RadGanttView - incorrect RowState of the DataBoundItem

To reproduce: please refer to the attached sample project. Try to edit the title for one of the child tasks in the grid and click the

Workaround:

private void radGanttView1_ItemChanged(object sender, Telerik.WinControls.UI.GanttViewItemChangedEventArgs e)
{
IEditableObject editebleObejct = e.Item.DataBoundItem as IEditableObject;
if (editebleObejct != null)
{
editebleObejct.EndEdit();
}
}
Bug Report by Desislava Yordanova Status: New Comments: 0 Attachments: 1 Category: RadGanttView Scheduled for: Not Scheduled Last update: 2017-07-20T08:04:50 by Desislava Yordanova
0
IvanT Todorov

FIX. RadPanel - controls in RadPanel redraw slowly when changing the Enabled state of the panel.

Controls in RadPanel redraw slowly when changing the Enabled state of the panel.
Bug Report by IvanT Todorov Status: Approved Comments: 1 Category: Panel Scheduled for: Not Scheduled Last update: 2017-07-19T20:58:47 by robert keltso
0
Desislava Yordanova
Team Member

FIX. RadRichTextEditor - characters spacing should be improved in order to look like RadRichTextBox and MS Word

RadRichTextEditor renders the text with a little bigger characters spacing than RadRichTextBox and MS Word.
Bug Report by Desislava Yordanova Status: Approved Comments: 3 Attachments: 2 Category: RadRichTextEditor Scheduled for: Not Scheduled Last update: 2017-07-19T10:57:02 by Hristo Merdjanov
0
Desislava Yordanova
Team Member

FIX. RadGridView - current state of the row is not updated when rows are added

To reproduce: please refer to the attached sample project and gif file illustrating the behavior. Add cell value in the new row and press teh down arrow.

Workaround: this.radGridView1.MasterTemplate.SelectLastAddedRow = false;

This problem is applicable for OpenEdge as well: http://knowledgebase.progress.com/articles/Article/Telerik-RadGridView-highlights-unnecessary-columns-and-rows-in-batch-mode
Bug Report by Desislava Yordanova Status: Completed Comments: 0 Attachments: 2 Category: RadGridView Scheduled for: R2 2017 SP1 Last update: 2017-07-18T09:56:36 by Ralitsa Kumanova
0
Hristo Merdjanov
Team Member

FIX. RadGridView - cannot paste data after read-only cells

How to reproduce
public partial class Form1 : RadForm
{
public Form1()
{
InitializeComponent();

GridViewTextBoxColumn textBoxColumn = new GridViewTextBoxColumn();
textBoxColumn.Name = "Column";
textBoxColumn.HeaderText = "Column";
this.radGridView1.MasterTemplate.Columns.Add(textBoxColumn);

GridViewTextBoxColumn textBoxColumn2 = new GridViewTextBoxColumn();
textBoxColumn2.Name = "TextBoxColumn2";
textBoxColumn2.HeaderText = "ReadOnlyColumn";
this.radGridView1.MasterTemplate.Columns.Add(textBoxColumn2);

for (int i = 0; i < 10; i++)
{
object v = i * 2;
if (i % 3 == 0)
{
v = null;
}

this.radGridView1.Rows.Add(new object[] { i, v });
}

this.radGridView1.MultiSelect = true;
foreach (var row in this.radGridView1.Rows)
{
foreach (var cell in row.Cells)
{
GridViewCellInfo cellInfo = cell as GridViewCellInfo;
if (cellInfo != null && cellInfo.RowInfo.Index % 3 == 0 && cellInfo.ColumnInfo.Index == 1)
{
cellInfo.ReadOnly = true;
}
}
}
}

}

Workaround:
public class MyRadGridView : RadGridView
{
public override string ThemeClassName
{
get
{
return typeof(RadGridView).FullName;
}
}

protected override RadGridViewElement CreateGridViewElement()
{
return new MyRadGridViewElement();
}
}

internal class MyRadGridViewElement : RadGridViewElement
{
protected override Type ThemeEffectiveType
{
get
{
return typeof(RadGridViewElement);
}
}

protected override MasterGridViewTemplate CreateTemplate()
{
return new MyMasterGridViewTemplate();
}
}

internal class MyMasterGridViewTemplate : MasterGridViewTemplate
{
protected override void PasteDataToRow(List<string> rowData, GridViewRowInfo row)
{
{
int colIndex = this.Owner.CurrentColumn.Index;
int j = 0;

while (j < rowData.Count && colIndex < this.CurrentView.ViewTemplate.ColumnCount)
{
GridViewColumn col = this.CurrentView.ViewTemplate.Columns[colIndex];
if (col.IsVisible && !col.ReadOnly && !row.Cells[colIndex].ReadOnly)
{

object value = rowData[j];

if (string.IsNullOrEmpty(rowData[j]))
{
value = null;
}
else if (this.CurrentView.ViewTemplate.Columns[colIndex].DataType == typeof(string))
{
GridViewTextBoxColumn textColumn = col as GridViewTextBoxColumn;

if (textColumn != null && textColumn.MaxLength > 0)
{
if (rowData[j].Length > textColumn.MaxLength)
{
value = rowData[j].Substring(0, textColumn.MaxLength);
}
}
}
else if (this.CurrentView.ViewTemplate.Columns[colIndex].DataType == typeof(DateTime))
{
try
{
value = DateTime.Parse(rowData[j], this.CurrentView.ViewTemplate.Columns[colIndex].FormatInfo);
}
catch { }
}
else if (this.CurrentView.ViewTemplate.Columns[colIndex].DataType == typeof(Color))
{
try
{
value = ColorTranslator.FromHtml(rowData[j]);
}
catch { }
}

if (this.ClipboardPasteMode == GridViewClipboardPasteMode.EnableWithNotifications)
{
CellValidatingEventArgs cellValidating = new CellValidatingEventArgs(row, col, value, row.Cells[colIndex].Value, null);
this.EventDispatcher.RaiseEvent<CellValidatingEventArgs>(EventDispatcher.CellValidating, this, cellValidating);

if (!cellValidating.Cancel)
{
row.Cells[colIndex].Value = value;

CellValidatedEventArgs cellValidated = new CellValidatedEventArgs(row, col, value);
this.EventDispatcher.RaiseEvent<CellValidatedEventArgs>(EventDispatcher.CellValidated, this, cellValidated);
}
}
else
{
row.Cells[colIndex].Value = value;
}

j++;
}

colIndex++;
}
}
}
}


Bug Report by Hristo Merdjanov Status: Completed Comments: 0 Category: RadGridView Scheduled for: R3 2017 Last update: 2017-07-17T14:36:55 by Ralitsa Kumanova
0
Desislava Yordanova
Team Member

FIX. RadGridView - NullReferenceException when copying an empty cell in GridViewSelectionMode.CellSelect

To reproduce: run the attached sample project:

1. Clear the value in one of the cells.
2. Select the empty cell and press Ctrl+C to copy the empty cell. You will encounter the error coming from the GetFormattedCellValue method.

Workaround: handle the RadGridView.Copying event

private void RadGridView1_Copying(object sender, GridViewClipboardEventArgs e)
{
if (this.radGridView1.SelectionMode == GridViewSelectionMode.FullRowSelect)
{
foreach (var row in this.radGridView1.SelectedRows)
{
foreach (var cell in row.Cells)
{
GridViewCellInfo cellInfo = cell as GridViewCellInfo;
if (cellInfo != null && cellInfo.Value == null)
{
cellInfo.Value = "";
}
}
}
}
else
{
foreach (var cell in this.radGridView1.SelectedCells)
{
if (cell.Value == null)
{
cell.Value = "";
}
}
}
}
Bug Report by Desislava Yordanova Status: Completed Comments: 0 Attachments: 2 Category: RadGridView Scheduled for: R3 2017 Last update: 2017-07-17T14:08:32 by Ralitsa Kumanova
0
Displaying items 1 - 10 of 5616