Introduce support for reordering items within a RadRibbonBarGroup, allowing new buttons to be inserted at any position and existing buttons to be moved between different RadRibbonBarGroups.
Passing a value near zero to the Thickness property of the RadialGaugeNeedle throws an exception.
In this scenario, we set the Thickness property to 0.0000003569. This is a positive value but very near zero. In that case, the internal logic will try to paint the distance by using LinearGradientBrush. As the points between the points is very small (less than a pixel), the LinearGradientBrush throws OutOfMemory exception.
The vertical and horizontal scrollbar positions get cached during scrolling. If you scroll around and then resize the RadRichTextEditor so that the scrollbars are no longer needed and then you resize the editor again to show the scrollbars, the cached position is used, instead of resetting it to 0,0.
This reproduces when the LayoutMode of the editor i set to FlowNoWrap.
To work this around, reset the scrollbars' Value to 0 on SizeChanged.
private void RadRichTextEditor1_SizeChanged(object sender, EventArgs e)
{
Normalize(radRichTextEditor1.RichTextBoxElement.VerticalScrollBar);
Normalize(radRichTextEditor1.RichTextBoxElement.HorizontalScrollBar);
}
private static void Normalize(RadScrollBarElement sb)
{
int maxUser = Math.Max(sb.Minimum, sb.Maximum - sb.LargeChange + 1);
if (sb.Visibility != ElementVisibility.Visible)
{
sb.Value = sb.Minimum;
return;
}
if (sb.Value > maxUser)
{
sb.Value = maxUser;
}
}
The last selected item is not tokenized when there isn't enough space, and it needs to move to the second line.
Add support for resizing the RadChat input text box, allowing users to adjust its height/width by dragging its top edge. This would make it easier to compose longer messages and provide a more flexible chat experience. The control should allow users to set the input area to their preferred size.
3D Charts will be a nice addition to the WinForms suite
On 125% dpi:
However, if you close the list and open it again, the list has the correct height (the gap is gone).
The reported behavior is observed in VisualStudio2022Light (or dark), VisualStudio2012, Office2013, Windows11.
When the BestFitColumns() method is used, the column width will be calculated to fit the content. In a scenario where the content is the longest one in the column, it will be next to the left and right side cell borders. When such a cell is selected and marked as a current cell, the current cell border will be applied, which will shrink the space for the content, and ellipses will appear.
The BestFitColumns() method needs to take into account the current cell border width in different themes.
I was trying to move the NewRow to the bottom of the RadVirtualGrid. This is also supported by its big brother RadGridView. I have now learned that this is not supported by RadVirtualGrid.
Hereby my request: Please support this!
I've created a Harmony patch (which works for me); it might help you if you decide to support it:
static class MoveNewRowToBottom
{
[HarmonyPatch(typeof(VirtualGridTableElement), "InvalidatePinnedRows")]
static class VirtualGridTableElement_InvalidatePinnedRows
{
static private bool _isInvalidating;
static private bool Prefix(VirtualGridTableElement __instance)
{
if (_isInvalidating)
return false;
_isInvalidating = true;
__instance.ViewElement.TopPinnedRows.DisposeChildren();
__instance.ViewElement.BottomPinnedRows.DisposeChildren();
var viewInfo = __instance.ViewInfo;
var rowsViewState = __instance.RowsViewState;
var topPinnedItems = rowsViewState.TopPinnedItems;
var bottomPinnedItems = rowsViewState.BottomPinnedItems;
if (viewInfo.ShowFilterRow)
if (!topPinnedItems.Contains(RadVirtualGrid.FilterRowIndex) && !bottomPinnedItems.Contains(RadVirtualGrid.FilterRowIndex))
rowsViewState.SetPinPosition(RadVirtualGrid.FilterRowIndex, PinnedRowPosition.Top);
if (viewInfo.ShowNewRow)
if (!topPinnedItems.Contains(RadVirtualGrid.NewRowIndex) && !bottomPinnedItems.Contains(RadVirtualGrid.NewRowIndex))
rowsViewState.SetPinPosition(RadVirtualGrid.NewRowIndex, PinnedRowPosition.Top);
if (viewInfo.ShowHeaderRow)
if (!topPinnedItems.Contains(RadVirtualGrid.HeaderRowIndex) && !bottomPinnedItems.Contains(RadVirtualGrid.HeaderRowIndex))
rowsViewState.SetPinPosition(RadVirtualGrid.HeaderRowIndex, PinnedRowPosition.Top);
var elementProvider = __instance.RowScroller.ElementProvider;
var topPinnedRows = __instance.ViewElement.TopPinnedRows;
foreach (int topPinnedRow in topPinnedItems.SortTopRowIndexes())
{
VirtualGridRowElement pinnedRow = (VirtualGridRowElement)elementProvider.GetElement(topPinnedRow, null);
topPinnedRows.Children.Add(pinnedRow);
pinnedRow.Attach(topPinnedRow, null);
}
var bottomPinnedRows = __instance.ViewElement.BottomPinnedRows;
foreach (int bottomPinnedRow in bottomPinnedItems.SortBottomRowIndexes())
{
VirtualGridRowElement pinnedRow = (VirtualGridRowElement)elementProvider.GetElement(bottomPinnedRow, null);
bottomPinnedRows.Children.Add(pinnedRow);
pinnedRow.Attach(bottomPinnedRow, null);
}
_isInvalidating = false;
return false;
}
}
static private IEnumerable<int> SortTopRowIndexes(this ReadOnlyCollection<int> topRowIndexes)
{
var specialRowIndex = topRowIndexes.Where(index => index < 0).ToList();
if (specialRowIndex.Contains(RadVirtualGrid.HeaderRowIndex))
yield return RadVirtualGrid.HeaderRowIndex;
if (specialRowIndex.Contains(RadVirtualGrid.NewRowIndex))
yield return RadVirtualGrid.NewRowIndex;
if (specialRowIndex.Contains(RadVirtualGrid.FilterRowIndex))
yield return RadVirtualGrid.FilterRowIndex;
foreach (var index in topRowIndexes.Where(index => index >= 0))
yield return index;
}
static private IEnumerable<int> SortBottomRowIndexes(this ReadOnlyCollection<int> bottomRowIndexes)
{
foreach (var index in bottomRowIndexes.Where(index => index >= 0))
yield return index;
var specialRowIndex = bottomRowIndexes.Where(index => index < 0).ToList();
if (specialRowIndex.Contains(RadVirtualGrid.FilterRowIndex))
yield return RadVirtualGrid.FilterRowIndex;
if (specialRowIndex.Contains(RadVirtualGrid.NewRowIndex))
yield return RadVirtualGrid.NewRowIndex;
if (specialRowIndex.Contains(RadVirtualGrid.HeaderRowIndex))
yield return RadVirtualGrid.HeaderRowIndex;
}
}
Repro-steps:
Expected behavior:
Observed behavior:
I traced the problem back to the method GridViewSleectedCellsCollection.IsSelected / GetHashCodeString.
internal bool IsSelected(GridViewRowInfo row, GridViewColumn column) => row != null && column is GridViewDataColumn && this.hashtable.Contains((object) this.GetHashCodeString(row, column));When a cell is selected with GridViewCellInfo.IsSelected = true, it checks if it has already been selected. It does so by calling GridViewSleectedCellsCollection.IsSelected. which checks if a HasCodeString is already in a hashtable. But, when another selected cell has the same HasCodeString, the result is (incorrectly) true, which will result in not added it to the collection of selected cells.
I guess that is can be easily fixed by changing:
private string GetHashCodeString(GridViewRowInfo row, GridViewColumn column)
{
int hashCode = row.GetHashCode();
string str1 = hashCode.ToString();
hashCode = column.GetHashCode();
string str2 = hashCode.ToString();
return str1 + str2;
}to:
private string GetHashCodeString(GridViewRowInfo row, GridViewColumn column)
{
int hashCode = row.GetHashCode();
string str1 = hashCode.ToString();
hashCode = column.GetHashCode();
string str2 = hashCode.ToString();
return str1 + "_" + str2;
}Since hashcodes 1 + 23 will result in the same string as hashcodes 12 + 3.
Making this change will reduce the problem significantly, but not entirely since hashCodes will never be unique.