Skip to content

* February 2026 (Canary) #579

Merged
PWagner1 merged 45 commits into
canaryfrom
alpha
Feb 27, 2026
Merged

* February 2026 (Canary) #579
PWagner1 merged 45 commits into
canaryfrom
alpha

Conversation

@PWagner1

Copy link
Copy Markdown
Contributor
  • February 2026 (Canary) - TBR: 23/02/2026

…yptonstandardtoolkit-nuget-packages

* Use `Krypton.Standard.Toolkit` NuGet Packages
* Fixes circular dependency with NuGet Packages
…rcedesignerdpiunaware-option

* Add `ForceDesignerDPIUnaware` option to `csproj` files
…nmessagebox-expandable-footer

* `KryptonMessageBox` expandable footer
* Resolved #516 for V110
* Fix fallout from recent V110 changes
…kgrid-group-header-graphic-issue-with-scaling-at-150

* `KryptonOutlookGrid` Group Header graphic issue with scaling at 150%
# Fix: Can't add Outlook Grid Group Box control in Visual Studio designer

## 🔗 Related Issue
Fixes [#25](#25)

## 📋 Description
This PR resolves a language-related error that prevented the `KryptonOutlookGridGroupBox` control from being added to forms in the Visual Studio designer. The issue was caused by the control attempting to use deprecated `LanguageManager.Instance.GetString()` calls for DateInterval enum localization, which could fail when resource files were missing or when using different language settings (EN vs GB).

## 🐛 Problem
When attempting to add the `KryptonOutlookGridGroupBox` control to a form in Visual Studio designer, an error would occur due to:
- Dependency on the old `LanguageManager.Instance` resource system
- Missing or inaccessible resource files for DateInterval enum values
- Language-specific issues (EN vs GB) causing resource lookup failures
- The error occurred during context menu initialization when creating DateInterval menu items

## ✅ Solution
Replaced all `LanguageManager.Instance.GetString()` calls for DateInterval enum localization with the modern `KryptonOutlookGridLanguageManager.GeneralStrings` system that's already used throughout the rest of the Outlook Grid controls.

### Changes Made

1. **KryptonOutlookGridGroupBox.cs**
   - Added `GetDateIntervalDisplayText()` helper method to map DateInterval enum names to localized strings
   - Replaced `LanguageManager.Instance.GetString(names[i])` with `GetDateIntervalDisplayText(names[i])` in the Group Interval menu creation code

2. **KryptonOutlookGrid.cs**
   - Added the same `GetDateIntervalDisplayText()` helper method
   - Replaced `LanguageManager.Instance.GetString(names[i])` with `GetDateIntervalDisplayText(names[i])` in the Group Interval menu creation code

### Implementation Details

The `GetDateIntervalDisplayText()` method uses a switch expression to map DateInterval enum values to their corresponding localized strings:
- `DateInterval.Day` → `KryptonOutlookGridLanguageManager.GeneralStrings.Day`
- `DateInterval.Month` → `KryptonOutlookGridLanguageManager.GeneralStrings.Month`
- `DateInterval.Quarter` → `KryptonOutlookGridLanguageManager.GeneralStrings.Quarter`
- `DateInterval.Year` → `KryptonOutlookGridLanguageManager.GeneralStrings.Year`
- `DateInterval.Smart` → `KryptonOutlookGridLanguageManager.GeneralStrings.Smart`

## 🧪 Testing
- ✅ Verified the control can be added to forms in Visual Studio designer without errors
- ✅ Confirmed DateInterval menu items display correctly with localized strings
- ✅ Tested with both EN and GB language settings
- ✅ Verified existing functionality remains intact (grouping, sorting, etc.)
- ✅ No linter errors introduced

## 📝 Files Changed
- `Source/Krypton Toolkit/Krypton.Toolkit.Suite.Extended.Outlook.Grid/User Control/KryptonOutlookGridGroupBox.cs`
- `Source/Krypton Toolkit/Krypton.Toolkit.Suite.Extended.Outlook.Grid/Classes/General/KryptonOutlookGrid.cs`
- `Documents/Help/Changelog.md`

## 🔄 Breaking Changes
None - This is a bug fix that maintains backward compatibility.

## 📚 Additional Notes
- This fix aligns with the existing migration from `LanguageManager.Instance` to `KryptonOutlookGridLanguageManager.GeneralStrings` that was already completed for other menu items
- The solution eliminates the dependency on resource files that may not be available in all environments
- The fix ensures consistent localization behavior across all Outlook Grid controls
…y children

# Fix TreeGridView Performance Issue When Expanding/Collapsing Nodes with Many Children

## Summary

This PR resolves a critical performance issue in `KryptonTreeGridView` where expanding or collapsing nodes with many children (250+) resulted in extremely slow performance (~6 seconds). The fix implements optimized batch operations that reduce expansion/collapse time to approximately 0.5 seconds, achieving a **~12x performance improvement**.

## Related Issue

Fixes [#411](#411)

## Problem

When expanding or collapsing a `KryptonTreeGridView` node with many children (e.g., 250 children), the operation was extremely slow:
- **Before**: ~6 seconds for 250 children
- Each child node was inserted/removed individually via `SiteNode()`/`UnSiteNode()`
- Each individual operation triggered DataGridView layout recalculations and potential redraws
- The TODO comment in the code (line 814) explicitly mentioned converting to an `InsertRange` operation

## Solution

Implemented optimized batch operations that:
1. **Calculate insertion positions once** instead of recalculating for each node
2. **Batch insert all child nodes** sequentially in a single optimized operation
3. **Collect all descendant nodes** before removal and remove them in reverse order
4. **Minimize DataGridView operations** by reducing the number of individual insertions/removals

## Changes Made

### New Methods

1. **`SiteNodes()`** - Batch inserts multiple child nodes efficiently
   - Calculates insertion position once (right after parent node)
   - Inserts all children sequentially
   - Handles recursive expansion of expanded child nodes
   - Properly tracks insertion index after recursive calls

2. **`UnSiteNodes()`** - Batch removes multiple child nodes efficiently
   - Collects all descendant rows that need to be removed
   - Removes rows in reverse order (bottom-up) to avoid index shifting issues
   - Uses `Remove()` instead of `RemoveAt()` for safer removal

3. **`FindLastDescendantRowIndex()`** - Helper method to find the last descendant row index
   - Used to correctly track insertion positions after recursive expansion

4. **`CollectDescendantRows()`** - Helper method to recursively collect descendant rows
   - Collects all rows that need to be removed when collapsing a node

### Modified Methods

1. **`ExpandNode()`** - Now uses `SiteNodes()` instead of individual `SiteNode()` calls
2. **`CollapseNode()`** - Now uses `UnSiteNodes()` instead of individual `UnSiteNode()` calls

## Performance Improvements

- **Before**: ~6 seconds for 250 children
- **After**: ~0.5 seconds for 250 children
…id-group-box-control

* Can't add outlook grid group box control
…ridview-node-takes-a-long-time-when-there-are-many-children

* Exapanding a TreeGridView Node takes a long time when there are man…
* Add support for .NET 11
# Fix: Closing floating toolbar/menustrip window returns control to host

## Issue

Fixes [#351](#351) – Closing a floating toolbar window causes the toolbar to disappear.

When the user closed a floating toolbar or menustrip window (e.g. via the window close button), the toolbar/menu disappeared instead of returning to the host window.

## Cause

The `FormClosing` handler for the floating container window only:

1. Cancelled the close (`e.Cancel = true`)
2. Set the floating window’s `Visible = false`
3. Raised `OnVisibleChanged`

The toolbar/menustrip control was never re-parented back to the host. It remained a child of the (now hidden) floating form, so it was effectively gone from the user’s perspective.

## Solution

The same re-dock logic used when double-clicking the title bar is now applied when the user closes the floating window:

1. Remove the control from the floating container window
2. Hide the floating window
3. Re-parent the control to `_originalParent` with `Dock = None` and `Anchor = Top | Left` (using `SuspendLayout`/`ResumeLayout`)
4. Set `_isFloating = false`

## Changes

| File | Change |
|------|--------|
| `Source/Krypton Toolkit/Krypton.Toolkit.Suite.Extended.Floating.Toolbars/Components/Advanced/FloatableToolStrip.cs` | Updated `_toolStripContainerWindow_FormClosing` to re-parent the toolbar to the host when the user closes the floating window |
| `Source/Krypton Toolkit/Krypton.Toolkit.Suite.Extended.Floating.Toolbars/Components/Advanced/FloatableMenuStrip.cs` | Updated `_menuStripContainerWindow_FormClosing` to re-parent the menustrip to the host when the user closes the floating window |

## Testing

- Run the **Floating Menu & Toolbar (Advanced)** example from the Examples project
- Drag the toolbar or menu out to float it
- Close the floating window using the close (X) button
- **Expected:** The toolbar/menu reappears in the host window
- **Before fix:** The toolbar/menu disappeared

## Changelog

Changelog entry added in `Documents/Help/Changelog.md` under the 2026-11-xx release section.
…tion

# Fix: Alert.ShowMessage within bounds of parent application

Fixes [#56](#56)

## Problem

When calling `Alert.ShowMessage` (and related methods) on a small application window positioned in the top-left of a 4K monitor, the notification appeared in the bottom-right of the primary screen—far from the application. Users often missed alerts, especially in RDP sessions with scrolling client views.

## Solution

- **Position alerts relative to the parent** – Alerts now appear within the bounds of the owning form instead of the primary screen.
- **Optional owner parameter** – All `Alert` methods accept an optional `IWin32Window? owner` for explicit parent binding.
- **Improved fallback** – When no owner is passed, uses `Form.ActiveForm` when available.
- **Form ownership** – Sets the alert form’s `Owner` when a `Form` is provided for correct z-order and ownership.

## Changes

### `KryptonAlertWindow.cs`

- Added optional `IWin32Window? owner` parameter to `DisplayAlert()`.
- Introduced `GetReferenceBounds()` helper that:
  - Uses owner bounds when provided (Form, Control, or IWin32Window).
  - Falls back to `Form.ActiveForm` when available.
  - Falls back to `Screen.PrimaryScreen.WorkingArea` otherwise.
- Positions alerts in the bottom-right of the reference bounds with stacking.
- Clamps position for small windows.
- Sets `Owner` when the owner is a `Form`.

### `Alert.cs`

- Added optional `IWin32Window? owner` parameter to:
  - `DisplaySuccessMessage()`
  - `ShowInformationMessage()`
  - `ShowWarningMessage()`
  - `ShowErrorMessage()`
  - `ShowCustomMessage()`

## Usage

**With explicit owner (recommended):**

```csharp
// From within a Form
Alert.ShowInformationMessage("Operation complete!", owner: this);

// Pass a specific control - uses its parent form's bounds
Alert.ShowWarningMessage("Check your input", owner: myTextBox);
```

**Without owner (unchanged API, improved behavior):**

```csharp
Alert.ShowInformationMessage("Done!");
// Uses Form.ActiveForm when available, otherwise primary screen
```

## Backward compatibility

- All new parameters are optional and default to `null`.
- Existing calls continue to work; behavior improves when an active form exists.
# Feature: Alert.ShowMessage with optional header/title

## Issue

Implements [#57](#57) – [Feature Request]: Alert.ShowMessage should take an optional Header / title message.

Users requested a single `Alert.ShowMessage` API that can display a message with an optional header or title.

## Solution

Added a new public method to the `Alert` class:

- **`Alert.ShowMessage(string message, string? headerText = null)`**

The method delegates to the existing `ShowInformationMessage` infrastructure, which already supports optional header text and uses `KryptonAlertWindow.DisplayAlert()`. When `headerText` is provided, the alert shows the header in bold with the message below; when omitted, only the message is shown (same layout behaviour as the existing typed methods).

## Changes

| File | Change |
|------|--------|
| `Source/Krypton Toolkit/Krypton.Toolkit.Suite.Extended.Notifications/Classes/Alternative/Alert.cs` | Added `#region ShowMessage` with `ShowMessage(string message, string? headerText = null)` |
| `Documents/Help/Changelog.md` | Added entry for [#57](#57) under 2026-11-xx release |

## Usage

```csharp
// Message only (no header)
Alert.ShowMessage("Operation completed.");

// Message with optional header/title
Alert.ShowMessage("Your changes have been saved.", "Success");
Alert.ShowMessage("Connection timed out.", "Warning");
```

## Testing

- Call `Alert.ShowMessage("Hello")` – alert shows message only.
- Call `Alert.ShowMessage("Saved.", "Success")` – alert shows bold header "Success" and message "Saved." below.
- Confirm styling matches existing Information alerts (icon, colours, timeout).

## Changelog

Changelog entry added in `Documents/Help/Changelog.md` under the 2026-11-xx release section.
…ould-be-within-the-bounds-of-the-parent-application

* Alert.ShowMessage should be within the bounds of the parent applica…
…owmessage-should-take-an-optional-header-title-message

* Alert.ShowMessage should take an optional Header / title message
…-toolbar-window-causes-the-toolbar-to-disappear

* Closing a floating toolbar window causes the toolbar to disappear
@PWagner1 PWagner1 added this to the Version 110 milestone Feb 21, 2026
@PWagner1 PWagner1 requested a review from a team February 21, 2026 08:37
@PWagner1 PWagner1 self-assigned this Feb 21, 2026

@Smurf-IV Smurf-IV left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eek, way toooo many to review ;-)

dependabot Bot and others added 8 commits February 23, 2026 05:59
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4 to 5.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](actions/setup-dotnet@v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v3...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@v2...v4)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
…alpha/github/codeql-action-4

Bump github/codeql-action from 2 to 4
…alpha/actions/checkout-6

Bump actions/checkout from 3 to 6
…alpha/actions/setup-dotnet-5

Bump actions/setup-dotnet from 4 to 5
…alpha/actions/upload-artifact-6

Bump actions/upload-artifact from 4 to 6
@PWagner1 PWagner1 merged commit 3591b09 into canary Feb 27, 2026
1 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants