Skip to content

fix: HandlerNotFoundException while debugging in Windows Machine mode#176

Merged
FreakyAli merged 11 commits intomasterfrom
r5-gh/fix/entry-imagesource
Apr 28, 2025
Merged

fix: HandlerNotFoundException while debugging in Windows Machine mode#176
FreakyAli merged 11 commits intomasterfrom
r5-gh/fix/entry-imagesource

Conversation

@FreakyAli
Copy link
Copy Markdown
Owner

@FreakyAli FreakyAli commented Apr 28, 2025

Summary by CodeRabbit

  • New Features
    • Introduced autocomplete functionality for Windows, allowing users to receive and select suggestions as they type.
    • Added a signature drawing feature for Windows, enabling users to draw directly on a canvas using pointer or mouse input.
    • Enhanced autocomplete view with customizable text alignment, font family, size, attributes, and text transformation options.
  • Chores
    • Updated project configuration to compile platform-specific code only for matching target frameworks, improving build accuracy and efficiency.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2025

Walkthrough

This update introduces Windows-specific handler implementations for two custom controls in the MAUI.FreakyControls library. The FreakyAutoCompleteViewHandler now inherits from ViewHandler, integrates the Windows AutoSuggestBox control, and manages event wiring for text changes, suggestion selection, and query submission. Similarly, the FreakySignatureCanvasViewHandler is updated to inherit from ViewHandler, create a Windows Canvas control, and handle pointer events to support drawing functionality. Both handlers now properly manage their event subscriptions and platform-specific UI integration, providing the necessary lifecycle methods for the Windows platform. Additionally, the project file was updated to exclude platform-specific source files from compilation when targeting non-matching frameworks. The interface IFreakyAutoCompleteView was extended with text formatting properties, and iOS-specific handlers and extensions were added to support font and text alignment mapping.

Changes

File(s) Change Summary
MAUI.FreakyControls/.../Platforms/Windows/FreakyAutoCompleteViewHandler.cs Converted FreakyAutoCompleteViewHandler to inherit from ViewHandler<FreakyAutoCompleteView, AutoSuggestBox>. Added a static property mapper and constructor. Implemented CreatePlatformView to instantiate an AutoSuggestBox with default placeholder and closed suggestions. Overrode ConnectHandler and DisconnectHandler to attach/detach event handlers for TextChanged, SuggestionChosen, and QuerySubmitted. Added stub event handler methods.
MAUI.FreakyControls/.../Platforms/Windows/FreakySignatureViewHandler.win.cs Updated FreakySignatureCanvasViewHandler to inherit from ViewHandler<FreakySignatureCanvasView, Canvas>. Added a static property mapper and constructor. Implemented CreatePlatformView to create a white-background Canvas. Overrode ConnectHandler and DisconnectHandler to manage pointer event handlers for drawing. Implemented drawing logic on pointer events, tracking drawing state and previous pointer position.
MAUI.FreakyControls/Maui.FreakyControls.csproj Modified project file to conditionally exclude platform-specific source files from compilation when the target framework does not match the platform. Added <ItemGroup> elements with conditions to remove platform-specific .cs files and folders from compilation for non-matching target frameworks, preventing cross-platform compilation of irrelevant files.
MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/IFreakyAutoCompleteView.cs Extended IFreakyAutoCompleteView interface with six new properties: HorizontalTextAlignment, VerticalTextAlignment (both TextAlignment), FontFamily (string), FontSize (double), FontAttributes (FontAttributes), and TextTransform (TextTransform) to control text appearance and layout.
MAUI.FreakyControls/.../Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs Added mapping methods in FreakyAutoCompleteViewHandler to support font and text alignment properties on iOS: MapHorizontalTextAlignment, MapVerticalTextAlignment, MapFontAttributes, MapFontFamily, MapFontSize, and MapTextTransform. Updated ConnectHandler to call update methods for font, alignment, and text transform (currently stubbed). Added private helper method for font descriptor conversion.
MAUI.FreakyControls/.../Platforms/iOS/NativeExtensions.cs Added two extension methods in NativeExtensions to convert Microsoft.Maui.TextAlignment values to iOS platform-specific enums: ToPlatform maps to UITextAlignment, and ToVPlatform maps to UIControlContentVerticalAlignment.
MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/FreakyAutoCompleteView.cs Added six new public properties (HorizontalTextAlignment, VerticalTextAlignment, FontFamily, FontSize, FontAttributes, TextTransform) throwing NotImplementedException as placeholders for text formatting and appearance control.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant FreakyAutoCompleteViewHandler
    participant AutoSuggestBox

    App->>FreakyAutoCompleteViewHandler: Instantiate handler
    FreakyAutoCompleteViewHandler->>AutoSuggestBox: CreatePlatformView()
    FreakyAutoCompleteViewHandler->>AutoSuggestBox: Attach event handlers (TextChanged, SuggestionChosen, QuerySubmitted)
    AutoSuggestBox-->>FreakyAutoCompleteViewHandler: Event (TextChanged/SuggestionChosen/QuerySubmitted)
    FreakyAutoCompleteViewHandler-->>App: Handle event (stubbed)
    App->>FreakyAutoCompleteViewHandler: Dispose handler
    FreakyAutoCompleteViewHandler->>AutoSuggestBox: Detach event handlers
Loading
sequenceDiagram
    participant App
    participant FreakySignatureCanvasViewHandler
    participant Canvas

    App->>FreakySignatureCanvasViewHandler: Instantiate handler
    FreakySignatureCanvasViewHandler->>Canvas: CreatePlatformView()
    FreakySignatureCanvasViewHandler->>Canvas: Attach pointer event handlers
    Canvas-->>FreakySignatureCanvasViewHandler: PointerPressed/PointerMoved/PointerReleased
    FreakySignatureCanvasViewHandler-->>Canvas: Draw line (on move)
    App->>FreakySignatureCanvasViewHandler: Dispose handler
    FreakySignatureCanvasViewHandler->>Canvas: Detach pointer event handlers
Loading

Poem

In Windows fields, two controls bloom anew,
One draws with a canvas, crisp and true.
The other suggests, as you type along,
With events all wired, it can't go wrong.
Handlers connect, then gently let go—
A hop, a skip, and off we go!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@FreakyAli FreakyAli linked an issue Apr 28, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs (1)

15-17: Consider removing the TODO comment

The comment "You can configure it further if needed" appears to be a placeholder that should be removed or replaced with actual configuration if needed.

        {
            IsSuggestionListOpen = false
-            // You can configure it further if needed
        };
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1)

46-53: Consider adding null check for PointerRoutedEventArgs

The OnPointerPressed method should include a null check for the event arguments to ensure robustness.

    private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
    {
+        if (e == null)
+            return;
            
        if (sender is not Canvas canvas)
            return;

        _isDrawing = true;
        _previousPoint = e.GetCurrentPoint(canvas).Position;
    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 317ad94 and 23ffe2e.

📒 Files selected for processing (2)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs (1 hunks)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-plugin-ci
🔇 Additional comments (4)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs (3)

8-19: Class now properly derives from ViewHandler for Windows platform

The implementation correctly inherits from ViewHandler<FreakyAutoCompleteView, AutoSuggestBox> and overrides CreatePlatformView() to return a new Windows-specific AutoSuggestBox control. This ensures proper integration with the MAUI handler architecture.


20-28: Proper event wiring in ConnectHandler

The handler correctly implements the ConnectHandler method to wire up the necessary events for the AutoSuggestBox control, which is essential for the autocomplete functionality to work properly.


30-38: Good practice - event cleanup in DisconnectHandler

The handler properly implements the DisconnectHandler method to clean up event subscriptions, which is important to prevent memory leaks. This is a good practice when working with platform-specific handlers.

MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1)

13-27: Handler properly implements ViewHandler for signature canvas

The implementation correctly inherits from ViewHandler<FreakySignatureCanvasView, Canvas> and creates a Windows-specific Canvas control with appropriate background color. This is a good implementation of the MAUI handler pattern.

Comment on lines +40 to +53
private void OnTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
// Handle text changed
}

private void OnSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
// Handle suggestion chosen
}

private void OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
// Handle query submitted
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Event handlers need implementation

The event handler methods contain only comments and don't actually implement any functionality. These need to be implemented to make the autocomplete feature work. You should forward these events to the virtual element (FreakyAutoCompleteView) or implement the autocomplete logic directly.

Here's a basic implementation example:

    private void OnTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
    {
-        // Handle text changed
+        if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
+        {
+            // Update suggestions based on text
+            if (VirtualView != null)
+            {
+                VirtualView.Text = sender.Text;
+                // Trigger the TextChanged event or command on the virtual view
+            }
+        }
    }

    private void OnSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
    {
-        // Handle suggestion chosen
+        if (VirtualView != null && args.SelectedItem != null)
+        {
+            // Handle the selected suggestion
+            // VirtualView.SelectedItem = args.SelectedItem;
+        }
    }

    private void OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
    {
-        // Handle query submitted
+        if (VirtualView != null)
+        {
+            // Handle query submission
+            // VirtualView.QuerySubmitted(sender.Text, args.ChosenSuggestion);
+        }
    }

Comment on lines +3 to +81
public partial class FreakySignatureCanvasViewHandler : ViewHandler<FreakySignatureCanvasView, Canvas>
{
} No newline at end of file
#if WINDOWS
protected override Canvas CreatePlatformView()
{
var canvas = new Canvas
{
Background = new SolidColorBrush(Colors.White)
};

canvas.PointerPressed += OnPointerPressed;
canvas.PointerMoved += OnPointerMoved;
canvas.PointerReleased += OnPointerReleased;
return canvas;
}

protected override void ConnectHandler(Canvas platformView)
{
base.ConnectHandler(platformView);
// Additional setup if needed
}

protected override void DisconnectHandler(Canvas platformView)
{
base.DisconnectHandler(platformView);
platformView.PointerPressed -= OnPointerPressed;
platformView.PointerMoved -= OnPointerMoved;
platformView.PointerReleased -= OnPointerReleased;
}

private bool _isDrawing;
private Windows.Foundation.Point _previousPoint;

private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
if (sender is not Canvas canvas)
return;

_isDrawing = true;
_previousPoint = e.GetCurrentPoint(canvas).Position;
}

private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
if (!_isDrawing || sender is not Canvas canvas)
return;

var currentPoint = e.GetCurrentPoint(canvas).Position;

var line = new Line
{
X1 = _previousPoint.X,
Y1 = _previousPoint.Y,
X2 = currentPoint.X,
Y2 = currentPoint.Y,
Stroke = new SolidColorBrush(Colors.Black),
StrokeThickness = 2
};

canvas.Children.Add(line);
_previousPoint = currentPoint;
}

private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
_isDrawing = false;
}
#endif
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add support for clearing the signature

The handler doesn't implement any method to clear the signature canvas. You should add a method to handle the clearing of the signature when requested by the virtual view.

Add a method to clear the canvas:

#if WINDOWS
    public void ClearSignature()
    {
        if (PlatformView != null)
        {
            PlatformView.Children.Clear();
        }
    }
#endif

And add a mapper for handling property changes:

public static PropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler> PropertyMapper = new(ViewHandler.ViewMapper)
{
    [nameof(FreakySignatureCanvasView.IsClear)] = MapIsClear
};

public static void MapIsClear(FreakySignatureCanvasViewHandler handler, FreakySignatureCanvasView view)
{
    if (view.IsClear)
    {
        handler.ClearSignature();
    }
}

Comment on lines +62 to +74
var line = new Line
{
X1 = _previousPoint.X,
Y1 = _previousPoint.Y,
X2 = currentPoint.X,
Y2 = currentPoint.Y,
Stroke = new SolidColorBrush(Colors.Black),
StrokeThickness = 2
};

canvas.Children.Add(line);
_previousPoint = currentPoint;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add customization from virtual view properties

The drawing implementation uses hardcoded values for stroke color and thickness. You should use properties from the virtual view to allow customization of the signature appearance.

        var line = new Line
        {
            X1 = _previousPoint.X,
            Y1 = _previousPoint.Y,
            X2 = currentPoint.X,
            Y2 = currentPoint.Y,
-            Stroke = new SolidColorBrush(Colors.Black),
-            StrokeThickness = 2
+            Stroke = new SolidColorBrush(VirtualView?.StrokeColor?.ToWindowsColor() ?? Colors.Black),
+            StrokeThickness = VirtualView?.StrokeThickness ?? 2
        };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var line = new Line
{
X1 = _previousPoint.X,
Y1 = _previousPoint.Y,
X2 = currentPoint.X,
Y2 = currentPoint.Y,
Stroke = new SolidColorBrush(Colors.Black),
StrokeThickness = 2
};
canvas.Children.Add(line);
_previousPoint = currentPoint;
}
var line = new Line
{
X1 = _previousPoint.X,
Y1 = _previousPoint.Y,
X2 = currentPoint.X,
Y2 = currentPoint.Y,
Stroke = new SolidColorBrush(VirtualView?.StrokeColor?.ToWindowsColor() ?? Colors.Black),
StrokeThickness = VirtualView?.StrokeThickness ?? 2
};
canvas.Children.Add(line);
_previousPoint = currentPoint;
}

Comment on lines +23 to +26
canvas.PointerPressed += OnPointerPressed;
canvas.PointerMoved += OnPointerMoved;
canvas.PointerReleased += OnPointerReleased;
return canvas;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Move event subscriptions to ConnectHandler

Event handlers are being attached in CreatePlatformView() but the common pattern is to attach them in ConnectHandler() for consistency with the MAUI handler lifecycle. In the current implementation, the events are attached in CreatePlatformView() but detached in DisconnectHandler().

    protected override Canvas CreatePlatformView()
    {
        var canvas = new Canvas
        {
            Background = new SolidColorBrush(Colors.White)
        };

-        canvas.PointerPressed += OnPointerPressed;
-        canvas.PointerMoved += OnPointerMoved;
-        canvas.PointerReleased += OnPointerReleased;
        return canvas;
    }

    protected override void ConnectHandler(Canvas platformView)
    {
        base.ConnectHandler(platformView);
-        // Additional setup if needed
+        platformView.PointerPressed += OnPointerPressed;
+        platformView.PointerMoved += OnPointerMoved;
+        platformView.PointerReleased += OnPointerReleased;
    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
canvas.PointerPressed += OnPointerPressed;
canvas.PointerMoved += OnPointerMoved;
canvas.PointerReleased += OnPointerReleased;
return canvas;
protected override Canvas CreatePlatformView()
{
var canvas = new Canvas
{
Background = new SolidColorBrush(Colors.White)
};
return canvas;
}
protected override void ConnectHandler(Canvas platformView)
{
base.ConnectHandler(platformView);
platformView.PointerPressed += OnPointerPressed;
platformView.PointerMoved += OnPointerMoved;
platformView.PointerReleased += OnPointerReleased;
}

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (4)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (3)

22-35: 🛠️ Refactor suggestion

Event handlers should be wired in ConnectHandler instead of CreatePlatformView.

The event handlers are being attached in CreatePlatformView() but should be moved to ConnectHandler() for consistency with the MAUI handler lifecycle pattern. This ensures proper separation between view creation and event wiring.

protected override Canvas CreatePlatformView()
{
    var canvas = new Canvas
    {
        Background = new SolidColorBrush(Colors.White)
    };

-   canvas.PointerPressed += OnPointerPressed;
-   canvas.PointerMoved += OnPointerMoved;
-   canvas.PointerReleased += OnPointerReleased;

    return canvas;
}

protected override void ConnectHandler(Canvas platformView)
{
    base.ConnectHandler(platformView);
+   platformView.PointerPressed += OnPointerPressed;
+   platformView.PointerMoved += OnPointerMoved;
+   platformView.PointerReleased += OnPointerReleased;
}

69-77: 🛠️ Refactor suggestion

Use stroke properties from the virtual view instead of hardcoded values.

The drawing implementation uses hardcoded values for stroke color and thickness. You should use the properties from the virtual view to allow customization of the signature appearance.

var line = new Line
{
    X1 = _previousPoint.X,
    Y1 = _previousPoint.Y,
    X2 = currentPoint.X,
    Y2 = currentPoint.Y,
-   Stroke = new SolidColorBrush(Colors.Black),
-   StrokeThickness = 2
+   Stroke = new SolidColorBrush(VirtualView?.StrokeColor?.ToWindowsColor() ?? Colors.Black),
+   StrokeThickness = VirtualView?.StrokeThickness ?? 2
};

50-60: 🛠️ Refactor suggestion

Missing implementation for clearing the signature.

The handler doesn't implement any method to clear the signature canvas when requested by the virtual view. You need to add property mapping and a clear method.

Add these mappings and method:

// Add to the property mapper
public static IPropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler> Mapper =
    new PropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler>(ViewHandler.ViewMapper)
    {
        [nameof(FreakySignatureCanvasView.IsClear)] = MapIsClear
    };

public static void MapIsClear(FreakySignatureCanvasViewHandler handler, FreakySignatureCanvasView view)
{
    if (view.IsClear)
    {
        handler.ClearSignature();
    }
}

// Add method to clear the signature
public void ClearSignature()
{
    if (PlatformView != null)
    {
        PlatformView.Children.Clear();
    }
}
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs (1)

45-58: ⚠️ Potential issue

Event handlers need implementation.

The event handler methods contain only TODO comments and don't actually implement any functionality. These need to be implemented to make the autocomplete feature work.

Here's a basic implementation example:

private void OnTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
-   // TODO: Handle text change
+   if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput && VirtualView != null)
+   {
+       VirtualView.Text = sender.Text;
+       VirtualView.TextChanged();
+   }
}

private void OnSuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
-   // TODO: Handle suggestion chosen
+   if (VirtualView != null && args.SelectedItem != null)
+   {
+       VirtualView.SelectedItem = args.SelectedItem;
+   }
}

private void OnQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
-   // TODO: Handle query submitted
+   if (VirtualView != null)
+   {
+       VirtualView.QuerySubmitted(sender.Text, args.ChosenSuggestion);
+   }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23ffe2e and c44a03b.

📒 Files selected for processing (2)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs (1 hunks)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-plugin-ci
🔇 Additional comments (3)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1)

13-20: Good implementation of the handler base class structure.

The class now properly inherits from ViewHandler<FreakySignatureCanvasView, Canvas> and sets up the property mapper. This structure aligns with the MAUI handler pattern and will allow the control to work correctly on Windows.

MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs (2)

8-15: Good implementation of the handler base class structure.

The class now properly inherits from ViewHandler<FreakyAutoCompleteView, AutoSuggestBox> and sets up the property mapper. This structure aligns with the MAUI handler pattern and will allow the control to work correctly on Windows.


27-43: LGTM! Good implementation of the event handler lifecycle.

The implementation correctly attaches event handlers in ConnectHandler and detaches them in DisconnectHandler, which follows the proper lifecycle pattern for MAUI handlers.

Comment on lines +17 to +25
#if WINDOWS
protected override AutoSuggestBox CreatePlatformView()
{
return new AutoSuggestBox
{
PlaceholderText = "Type here...",
IsSuggestionListOpen = false
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

PlaceholderText should be mapped from the virtual view property.

Currently, the placeholder text is hardcoded to "Type here...". Instead, you should use the placeholder text from the virtual view to ensure consistency with cross-platform settings.

protected override AutoSuggestBox CreatePlatformView()
{
    return new AutoSuggestBox
    {
-       PlaceholderText = "Type here...",
+       PlaceholderText = VirtualView?.Placeholder ?? "Type here...",
        IsSuggestionListOpen = false
    };
}

Comment on lines +10 to +11
public static IPropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler> Mapper =
new PropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler>(ViewHandler.ViewMapper);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add property mappings for common properties.

The Mapper doesn't contain any specific property mappings. You should add mappings for Text, Placeholder, and ItemsSource to sync the virtual view with the platform view.

public static IPropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler> Mapper =
-   new PropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler>(ViewHandler.ViewMapper);
+   new PropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler>(ViewHandler.ViewMapper)
+   {
+       [nameof(FreakyAutoCompleteView.Text)] = MapText,
+       [nameof(FreakyAutoCompleteView.Placeholder)] = MapPlaceholder,
+       [nameof(FreakyAutoCompleteView.ItemsSource)] = MapItemsSource
+   };

+ public static void MapText(FreakyAutoCompleteViewHandler handler, FreakyAutoCompleteView view)
+ {
+     handler.PlatformView.Text = view.Text;
+ }
+
+ public static void MapPlaceholder(FreakyAutoCompleteViewHandler handler, FreakyAutoCompleteView view)
+ {
+     handler.PlatformView.PlaceholderText = view.Placeholder;
+ }
+
+ public static void MapItemsSource(FreakyAutoCompleteViewHandler handler, FreakyAutoCompleteView view)
+ {
+     handler.PlatformView.ItemsSource = view.ItemsSource;
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static IPropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler> Mapper =
new PropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler>(ViewHandler.ViewMapper);
public static IPropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler> Mapper =
new PropertyMapper<FreakyAutoCompleteView, FreakyAutoCompleteViewHandler>(ViewHandler.ViewMapper)
{
[nameof(FreakyAutoCompleteView.Text)] = MapText,
[nameof(FreakyAutoCompleteView.Placeholder)] = MapPlaceholder,
[nameof(FreakyAutoCompleteView.ItemsSource)] = MapItemsSource
};
public static void MapText(FreakyAutoCompleteViewHandler handler, FreakyAutoCompleteView view)
{
handler.PlatformView.Text = view.Text;
}
public static void MapPlaceholder(FreakyAutoCompleteViewHandler handler, FreakyAutoCompleteView view)
{
handler.PlatformView.PlaceholderText = view.Placeholder;
}
public static void MapItemsSource(FreakyAutoCompleteViewHandler handler, FreakyAutoCompleteView view)
{
handler.PlatformView.ItemsSource = view.ItemsSource;
}

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (3)

31-34: 🛠️ Refactor suggestion

Move event subscriptions to ConnectHandler

Event handlers are being attached in CreatePlatformView() but the common pattern is to attach them in ConnectHandler() for consistency with the MAUI handler lifecycle. This ensures proper synchronization with the MAUI control lifecycle.

    protected override Canvas CreatePlatformView()
    {
        var canvas = new Canvas
        {
            Background = new SolidColorBrush(Colors.White)
        };

-        canvas.PointerPressed += OnPointerPressed;
-        canvas.PointerMoved += OnPointerMoved;
-        canvas.PointerReleased += OnPointerReleased;

        return canvas;
    }

    protected override void ConnectHandler(Canvas platformView)
    {
        base.ConnectHandler(platformView);
+        platformView.PointerPressed += OnPointerPressed;
+        platformView.PointerMoved += OnPointerMoved;
+        platformView.PointerReleased += OnPointerReleased;
    }

76-77: 🛠️ Refactor suggestion

Use virtual view properties for drawing customization

The drawing implementation uses hardcoded values for stroke color and thickness instead of properties from the virtual view.

    var line = new Line
    {
        X1 = _previousPoint.X,
        Y1 = _previousPoint.Y,
        X2 = currentPoint.X,
        Y2 = currentPoint.Y,
-       Stroke = new SolidColorBrush(Colors.Black),
-       StrokeThickness = 2
+       Stroke = new SolidColorBrush(VirtualView?.StrokeColor?.ToWindowsColor() ?? Colors.Black),
+       StrokeThickness = VirtualView?.StrokeThickness ?? 2
    };

51-89: 🛠️ Refactor suggestion

Add support for clearing the signature

The handler doesn't implement any method to clear the signature canvas. You should add a method to handle the clearing when requested by the virtual view.

#if WINDOWS
    public void ClearSignature()
    {
        if (PlatformView != null)
        {
            PlatformView.Children.Clear();
        }
    }
#endif
🧹 Nitpick comments (1)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1)

64-82: Add bounds checking for drawing operations

The current implementation doesn't check if drawing operations stay within the canvas bounds. This could lead to drawing outside the visible area or cause unexpected behavior.

    private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (!_isDrawing || sender is not Canvas canvas)
            return;

        var currentPoint = e.GetCurrentPoint(canvas).Position;

+       // Ensure points are within canvas bounds
+       currentPoint.X = Math.Clamp(currentPoint.X, 0, canvas.ActualWidth);
+       currentPoint.Y = Math.Clamp(currentPoint.Y, 0, canvas.ActualHeight);

        var line = new Line
        {
            X1 = _previousPoint.X,
            Y1 = _previousPoint.Y,
            X2 = currentPoint.X,
            Y2 = currentPoint.Y,
            Stroke = new SolidColorBrush(Colors.Black),
            StrokeThickness = 2
        };

        canvas.Children.Add(line);
        _previousPoint = currentPoint;
    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c44a03b and 127a48f.

📒 Files selected for processing (1)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-plugin-ci

Comment on lines +14 to +89
public partial class FreakySignatureCanvasViewHandler : ViewHandler<FreakySignatureCanvasView, Canvas>
{
public static IPropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler> Mapper =
new PropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler>(ViewHandler.ViewMapper);

public FreakySignatureCanvasViewHandler() : base(Mapper)
{
}

#if WINDOWS
protected override Canvas CreatePlatformView()
{
var canvas = new Canvas
{
Background = new SolidColorBrush(Colors.White)
};

canvas.PointerPressed += OnPointerPressed;
canvas.PointerMoved += OnPointerMoved;
canvas.PointerReleased += OnPointerReleased;

return canvas;
}

protected override void ConnectHandler(Canvas platformView)
{
base.ConnectHandler(platformView);
}

protected override void DisconnectHandler(Canvas platformView)
{
base.DisconnectHandler(platformView);
platformView.PointerPressed -= OnPointerPressed;
platformView.PointerMoved -= OnPointerMoved;
platformView.PointerReleased -= OnPointerReleased;
}

private bool _isDrawing;
private Windows.Foundation.Point _previousPoint;

private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
if (sender is not Canvas canvas)
return;

_isDrawing = true;
_previousPoint = e.GetCurrentPoint(canvas).Position;
}

private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
if (!_isDrawing || sender is not Canvas canvas)
return;

var currentPoint = e.GetCurrentPoint(canvas).Position;

var line = new Line
{
X1 = _previousPoint.X,
Y1 = _previousPoint.Y,
X2 = currentPoint.X,
Y2 = currentPoint.Y,
Stroke = new SolidColorBrush(Colors.Black),
StrokeThickness = 2
};

canvas.Children.Add(line);
_previousPoint = currentPoint;
}

private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
_isDrawing = false;
}
#endif
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add support for capturing the signature image

The handler doesn't implement functionality to capture the drawn signature as an image. This is typically a key feature for signature controls.

#if WINDOWS
    public async Task<Stream> GetImageStreamAsync(ImageFormat format)
    {
        if (PlatformView == null)
            return null;
            
        // Render the canvas to a RenderTargetBitmap
        var rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(PlatformView);
        
        // Convert to stream in the requested format
        var stream = new InMemoryRandomAccessStream();
        var encoder = await BitmapEncoder.CreateAsync(
            format == ImageFormat.Png ? BitmapEncoder.PngEncoderId : BitmapEncoder.JpegEncoderId, 
            stream);
            
        var pixelBuffer = await rtb.GetPixelsAsync();
        encoder.SetPixelData(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Premultiplied,
            (uint)rtb.PixelWidth,
            (uint)rtb.PixelHeight,
            96,
            96,
            pixelBuffer.ToArray());
            
        await encoder.FlushAsync();
        
        // Convert to MemoryStream for cross-platform compatibility
        var ms = new MemoryStream();
        var reader = new DataReader(stream.GetInputStreamAt(0));
        await reader.LoadAsync((uint)stream.Size);
        byte[] bytes = new byte[stream.Size];
        reader.ReadBytes(bytes);
        ms.Write(bytes, 0, bytes.Length);
        ms.Position = 0;
        
        return ms;
    }
#endif

Would you like me to add mapper code to support this functionality as well?

Comment on lines +16 to +17
public static IPropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler> Mapper =
new PropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler>(ViewHandler.ViewMapper);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Implement property mappings for signature customization

The property mapper is defined but doesn't map any properties specific to the signature view, such as stroke color, thickness, or clear functionality.

    public static IPropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler> Mapper =
-       new PropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler>(ViewHandler.ViewMapper);
+       new PropertyMapper<FreakySignatureCanvasView, FreakySignatureCanvasViewHandler>(ViewHandler.ViewMapper)
+       {
+           [nameof(FreakySignatureCanvasView.StrokeColor)] = MapStrokeColor,
+           [nameof(FreakySignatureCanvasView.StrokeThickness)] = MapStrokeThickness,
+           [nameof(FreakySignatureCanvasView.IsClear)] = MapIsClear
+       };

+   public static void MapStrokeColor(FreakySignatureCanvasViewHandler handler, FreakySignatureCanvasView view)
+   {
+       // Update stroke color if needed
+   }
+
+   public static void MapStrokeThickness(FreakySignatureCanvasViewHandler handler, FreakySignatureCanvasView view)
+   {
+       // Update stroke thickness if needed
+   }
+
+   public static void MapIsClear(FreakySignatureCanvasViewHandler handler, FreakySignatureCanvasView view)
+   {
+       if (view.IsClear)
+       {
+           handler.ClearSignature();
+       }
+   }

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1dba13 and 83929ca.

📒 Files selected for processing (2)
  • MAUI.FreakyControls/MAUI.FreakyControls/Maui.FreakyControls.csproj (1 hunks)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs

Comment on lines +176 to +182
<!-- Android -->
<ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-android')) != true">
<Compile Remove="**\*.Android.cs" />
<None Include="**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\Android\**\*.cs" />
<None Include="**\Android\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix MSBuild Condition syntax for Android file exclusion.

The Condition attribute is using $(TargetFramework.StartsWith('net9.0-android')) != true, which isn’t a valid MSBuild property function. You need to invoke .NET string methods via the $([System.String]::…) syntax so the condition evaluates correctly per target framework.

Apply this diff to correct the ItemGroup header:

- <ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-android')) != true">
+ <ItemGroup Condition="$([System.String]::StartsWith('$(TargetFramework)', 'net9.0-android')) == 'false'">

Comment on lines +200 to +206
<!-- Windows -->
<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true">
<Compile Remove="**\*.Windows.cs" />
<None Include="**\*.Windows.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\Windows\**\*.cs" />
<None Include="**\Windows\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix MSBuild Condition syntax for Windows file exclusion.

The Windows block uses $(TargetFramework.Contains('-windows')), which isn’t valid in MSBuild. Use the property‐function syntax instead:

Suggested diff:

- <ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true">
+ <ItemGroup Condition="$([System.String]::Contains('$(TargetFramework)', '-windows')) == 'false'">

Comment on lines +184 to +190
<!-- iOS -->
<ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-ios')) != true">
<Compile Remove="**\*.iOS.cs" />
<None Include="**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\iOS\**\*.cs" />
<None Include="**\iOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix MSBuild Condition syntax for iOS file exclusion.

Similarly, the iOS block’s Condition uses $(TargetFramework.StartsWith('net9.0-ios')), which won’t be recognized. Switch to the MSBuild property‐function form:

Suggested change:

- <ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-ios')) != true">
+ <ItemGroup Condition="$([System.String]::StartsWith('$(TargetFramework)', 'net9.0-ios')) == 'false'">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<!-- iOS -->
<ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-ios')) != true">
<Compile Remove="**\*.iOS.cs" />
<None Include="**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\iOS\**\*.cs" />
<None Include="**\iOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
<!-- iOS -->
<ItemGroup Condition="$([System.String]::StartsWith('$(TargetFramework)', 'net9.0-ios')) == 'false'">
<Compile Remove="**\*.iOS.cs" />
<None Include="**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\iOS\**\*.cs" />
<None Include="**\iOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

Comment on lines +192 to +198
<!-- Mac Catalyst -->
<ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-maccatalyst')) != true">
<Compile Remove="**\*.MacCatalyst.cs" />
<None Include="**\*.MacCatalyst.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\MacCatalyst\**\*.cs" />
<None Include="**\MacCatalyst\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix MSBuild Condition syntax for Mac Catalyst file exclusion.

The Mac Catalyst block also uses the unsupported $(TargetFramework.StartsWith('net9.0-maccatalyst')). Update it to call the .NET string method correctly:

Apply this diff:

- <ItemGroup Condition="$(TargetFramework.StartsWith('net9.0-maccatalyst')) != true">
+ <ItemGroup Condition="$([System.String]::StartsWith('$(TargetFramework)', 'net9.0-maccatalyst')) == 'false'">

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (2)
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/NativeExtensions.cs (1)

32-45: Consider using consistent switch syntax style.

While the implementation is correct, you're using different switch styles between this method and the previous one. For better code consistency, consider using the same syntax style in both methods.

-    public static UIControlContentVerticalAlignment ToVPlatform(this Microsoft.Maui.TextAlignment alignment)
-    {
-        switch (alignment)
-        {
-            case Microsoft.Maui.TextAlignment.Start:
-                return UIControlContentVerticalAlignment.Top;
-            case Microsoft.Maui.TextAlignment.Center:
-                return UIControlContentVerticalAlignment.Center;
-            case Microsoft.Maui.TextAlignment.End:
-                return UIControlContentVerticalAlignment.Bottom;
-            default:
-                return UIControlContentVerticalAlignment.Center; // Default to center
-        }
-    }
+    public static UIControlContentVerticalAlignment ToVPlatform(this Microsoft.Maui.TextAlignment alignment)
+    {
+        return alignment switch
+        {
+            Microsoft.Maui.TextAlignment.Start => UIControlContentVerticalAlignment.Top,
+            Microsoft.Maui.TextAlignment.Center => UIControlContentVerticalAlignment.Center,
+            Microsoft.Maui.TextAlignment.End => UIControlContentVerticalAlignment.Bottom,
+            _ => UIControlContentVerticalAlignment.Center, // Default to center
+        };
+    }
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs (1)

237-248: Defined but unused helper method.

This helper method UIFontDescriptorFromAttributes is defined but never used in the file. Either use it in the font handling logic or remove it if not needed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83929ca and 4e4b933.

📒 Files selected for processing (4)
  • MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/IFreakyAutoCompleteView.cs (1 hunks)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs (1 hunks)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs (2 hunks)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/NativeExtensions.cs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • MAUI.FreakyControls/MAUI.FreakyControls/Platforms/Windows/FreakySignatureViewHandler.win.cs
🧰 Additional context used
🪛 GitHub Check: CodeFactor
MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs

[notice] 267-267: MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs#L267
A closing brace should not be preceded by a blank line. (SA1508)


[notice] 265-265: MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs#L265
An opening brace should not be followed by a blank line. (SA1505)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-plugin-ci
🔇 Additional comments (5)
MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/IFreakyAutoCompleteView.cs (1)

18-23: Interface extension looks good!

These new text formatting properties (alignment, font properties, and text transformation) will enable more granular control over the appearance of the auto-complete view. The property types are appropriate and consistent with MAUI conventions.

MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/NativeExtensions.cs (1)

21-30: LGTM - Good implementation of TextAlignment extension method.

The mapping from MAUI TextAlignment to UIKit.UITextAlignment is correctly implemented with appropriate default handling.

MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs (3)

26-28: Added initialization for new text formatting properties.

You've correctly added the initial calls to update font, text alignment, and text transformation in the ConnectHandler method.


188-191: LGTM - HorizontalTextAlignment mapping looks good.

The implementation correctly uses the extension method to convert MAUI TextAlignment to UIKit.UITextAlignment.


193-196: LGTM - VerticalTextAlignment mapping looks good.

The implementation correctly uses the extension method to convert MAUI TextAlignment to UIControlContentVerticalAlignment.

Comment on lines +217 to +221
public static void MapFontFamily(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
{
var font = UIFont.FromName(view.FontFamily, (float)view.FontSize);
handler.PlatformView.Font = font;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Font family setting may override font attributes.

This method sets the font based on fontFamily and fontSize but does not account for fontAttributes (bold/italic). If both properties are set, the behavior depends on which mapper runs last.

Consider a combined approach that respects all font properties:

-    public static void MapFontFamily(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
-    {
-        var font = UIFont.FromName(view.FontFamily, (float)view.FontSize);
-        handler.PlatformView.Font = font;
-    }
+    public static void MapFontFamily(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
+    {
+        // If custom font family is specified
+        if (!string.IsNullOrEmpty(view.FontFamily))
+        {
+            UIFont font = UIFont.FromName(view.FontFamily, (float)view.FontSize);
+            
+            // If font creation succeeded and attributes are specified
+            if (font != null && view.FontAttributes != FontAttributes.None)
+            {
+                // Try to create a font with the attributes
+                var descriptor = font.FontDescriptor.CreateWithTraits(UIFontDescriptorFromAttributes(view.FontAttributes));
+                UIFont attributedFont = UIFont.FromDescriptor(descriptor, (float)view.FontSize);
+                
+                // Use the attributed font if available, otherwise fall back to the regular font
+                handler.PlatformView.Font = attributedFont ?? font;
+            }
+            else
+            {
+                handler.PlatformView.Font = font;
+            }
+        }
+    }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +264 to +267
private void UpdateTextTransform(FreakyNativeAutoCompleteView platformView)
{

}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Empty implementation with formatting issue.

The UpdateTextTransform method is called in ConnectHandler but has an empty implementation with a blank line that violates style rules.

Fix both the implementation and formatting:

     private void UpdateTextTransform(FreakyNativeAutoCompleteView platformView)
     {
-        
+        if (VirtualView != null)
+        {
+            MapTextTransform(this, VirtualView);
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private void UpdateTextTransform(FreakyNativeAutoCompleteView platformView)
{
}
private void UpdateTextTransform(FreakyNativeAutoCompleteView platformView)
{
if (VirtualView != null)
{
MapTextTransform(this, VirtualView);
}
}
🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 267-267: MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs#L267
A closing brace should not be preceded by a blank line. (SA1508)


[notice] 265-265: MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs#L265
An opening brace should not be followed by a blank line. (SA1505)

Comment on lines +223 to +226
public static void MapFontSize(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
{
handler.PlatformView.Font = UIFont.SystemFontOfSize((float)view.FontSize);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

FontSize setter may override other font settings.

This method sets a system font with the specified size, but it doesn't preserve any font family or attributes that might have been set previously.

Consider this alternative approach:

-    public static void MapFontSize(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
-    {
-        handler.PlatformView.Font = UIFont.SystemFontOfSize((float)view.FontSize);
-    }
+    public static void MapFontSize(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
+    {
+        // Get current font
+        UIFont currentFont = handler.PlatformView.Font;
+        
+        // If we have a current font, try to resize it
+        if (currentFont != null)
+        {
+            // Create a new font with the same family but new size
+            UIFont resizedFont = UIFont.FromName(currentFont.FamilyName, (float)view.FontSize);
+            if (resizedFont != null)
+            {
+                handler.PlatformView.Font = resizedFont;
+                return;
+            }
+        }
+        
+        // Fallback to system font if no current font or resize failed
+        handler.PlatformView.Font = UIFont.SystemFontOfSize((float)view.FontSize);
+    }

Comment on lines +260 to +262
private void UpdateTextAlignment(FreakyNativeAutoCompleteView platformView)
{
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Empty implementation method.

The UpdateTextAlignment method is called in ConnectHandler but has an empty implementation. Implement it to properly initialize text alignment.

     private void UpdateTextAlignment(FreakyNativeAutoCompleteView platformView)
     {
+        if (VirtualView != null)
+        {
+            MapHorizontalTextAlignment(this, VirtualView);
+            MapVerticalTextAlignment(this, VirtualView);
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private void UpdateTextAlignment(FreakyNativeAutoCompleteView platformView)
{
}
private void UpdateTextAlignment(FreakyNativeAutoCompleteView platformView)
{
if (VirtualView != null)
{
MapHorizontalTextAlignment(this, VirtualView);
MapVerticalTextAlignment(this, VirtualView);
}
}

Comment on lines +255 to +258
private void UpdateFont(FreakyNativeAutoCompleteView platformView)
{
//platformView.font(VirtualView?.TextColor);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Empty implementation with commented code.

The UpdateFont method is called in ConnectHandler but has only a commented-out implementation. This method should either be implemented or removed if not needed.

If this method is intended to be used, implement it by calling the appropriate mappers:

     private void UpdateFont(FreakyNativeAutoCompleteView platformView)
     {
-        //platformView.font(VirtualView?.TextColor);
+        if (VirtualView != null)
+        {
+            MapFontFamily(this, VirtualView);
+            MapFontAttributes(this, VirtualView);
+            MapFontSize(this, VirtualView);
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private void UpdateFont(FreakyNativeAutoCompleteView platformView)
{
//platformView.font(VirtualView?.TextColor);
}
private void UpdateFont(FreakyNativeAutoCompleteView platformView)
{
if (VirtualView != null)
{
MapFontFamily(this, VirtualView);
MapFontAttributes(this, VirtualView);
MapFontSize(this, VirtualView);
}
}

Comment on lines +228 to +234
public static void MapTextTransform(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
{
if (view.TextTransform == TextTransform.Uppercase)
handler.PlatformView.Text = handler.PlatformView.Text.ToUpper();
else if (view.TextTransform == TextTransform.Lowercase)
handler.PlatformView.Text = handler.PlatformView.Text.ToLower();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

TextTransform implementation might not handle text changes.

The current implementation directly modifies the text when the TextTransform property changes, but it doesn't account for subsequent text changes. This might lead to inconsistent behavior.

Consider implementing a transform method that is called whenever text changes:

     public static void MapTextTransform(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
     {
-        if (view.TextTransform == TextTransform.Uppercase)
-            handler.PlatformView.Text = handler.PlatformView.Text.ToUpper();
-        else if (view.TextTransform == TextTransform.Lowercase)
-            handler.PlatformView.Text = handler.PlatformView.Text.ToLower();
+        // Store the transform setting in the platform view 
+        handler.PlatformView.TextTransform = view.TextTransform;
+        
+        // Apply transform to current text
+        if (!string.IsNullOrEmpty(handler.PlatformView.Text))
+        {
+            handler.PlatformView.Text = ApplyTextTransform(handler.PlatformView.Text, view.TextTransform);
+        }
     }
+    
+    // Helper to apply text transformation
+    private static string ApplyTextTransform(string text, TextTransform transform)
+    {
+        return transform switch
+        {
+            TextTransform.Uppercase => text.ToUpper(),
+            TextTransform.Lowercase => text.ToLower(),
+            _ => text,
+        };
+    }

You would also need to modify the text change event handler to apply the transform to new text.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static void MapTextTransform(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
{
if (view.TextTransform == TextTransform.Uppercase)
handler.PlatformView.Text = handler.PlatformView.Text.ToUpper();
else if (view.TextTransform == TextTransform.Lowercase)
handler.PlatformView.Text = handler.PlatformView.Text.ToLower();
}
public static void MapTextTransform(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
{
// Store the transform setting in the platform view
handler.PlatformView.TextTransform = view.TextTransform;
// Apply transform to current text
if (!string.IsNullOrEmpty(handler.PlatformView.Text))
{
handler.PlatformView.Text = ApplyTextTransform(handler.PlatformView.Text, view.TextTransform);
}
}
// Helper to apply text transformation
private static string ApplyTextTransform(string text, TextTransform transform)
{
return transform switch
{
TextTransform.Uppercase => text.ToUpper(),
TextTransform.Lowercase => text.ToLower(),
_ => text,
};
}

Comment on lines +198 to +215
public static void MapFontAttributes(FreakyAutoCompleteViewHandler handler, IFreakyAutoCompleteView view)
{
// If the FontAttributes is Bold
if (view.FontAttributes == FontAttributes.Bold)
{
handler.PlatformView.Font = UIFont.BoldSystemFontOfSize((nfloat)view.FontSize);
}
// If the FontAttributes is Italic
else if (view.FontAttributes == FontAttributes.Italic)
{
handler.PlatformView.Font = UIFont.ItalicSystemFontOfSize((nfloat)view.FontSize);
}
// If it's neither Bold nor Italic, set to normal font
else
{
handler.PlatformView.Font = UIFont.SystemFontOfSize((nfloat)view.FontSize);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Font attributes may be overridden by other font setting methods.

The MapFontAttributes method correctly sets font based on bold/italic attributes, but this might be overridden if MapFontFamily or MapFontSize is called afterward. Consider a more integrated approach to font handling.

Check if there's a designated order of property mapping methods in MAUI handlers or if you need to implement a combined font handling approach:


🏁 Script executed:

#!/bin/bash
# Look for patterns of font handling in other MAUI handlers
rg -A 5 -B 5 "FontAttributes|FontFamily|FontSize" --type cs

Length of output: 66607


🏁 Script executed:

#!/bin/bash
# Show the beginning of the iOS handler to inspect property mapper registration
sed -n '1,200p' MAUI.FreakyControls/MAUI.FreakyControls/Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs

Length of output: 8843


Combine font mapping to avoid one override another

Currently in Platforms/iOS/FreakyAutoCompleteViewHandler.ios.cs you have:

  • MapFontAttributes (lines 198–215)
  • MapFontFamily
  • MapFontSize

Each of these independently does

handler.PlatformView.Font =;

so a later change to FontFamily or FontSize will wipe out any Bold/Italic traits you applied earlier (and vice versa).

• Refactor into a single MapFont method that reads all three properties at once—FontFamily, FontSize and FontAttributes—and uses a UIFontDescriptor to combine them. For example:

var family   = view.FontFamily ?? UIFont.SystemFontOfSize(view.FontSize).Name;
var descriptor = UIFontDescriptor.FromName(family, (nfloat)view.FontSize)
    .CreateWithTraits(UIFontDescriptorFromAttributes(view.FontAttributes));
handler.PlatformView.Font = UIFont.FromDescriptor(descriptor, (nfloat)view.FontSize);

• Update your property mapper to call only this unified MapFont instead of three separate handlers.

This ensures you never lose the requested font style when any one of those properties changes.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/FreakyAutoCompleteView.cs (1)

1-251: 💡 Verification agent

🧩 Analysis chain

Verify that Windows platform handler is correctly set up to map these new properties

According to the PR title, this fixes a HandlerNotFoundException issue in Windows Machine mode. The addition of these text formatting properties should be connected to the Windows platform handler implementation to ensure it can properly map these properties.

Let's verify that the Windows handler implementation exists and properly maps these new properties:


🏁 Script executed:

#!/bin/bash
# Check the Windows platform handler implementation
echo "Checking Windows platform handler implementation..."
fd "FreakyAutoCompleteViewHandler" --type f --glob "*.cs" | xargs cat

Length of output: 274


🏁 Script executed:

#!/bin/bash
echo "Locating Windows handler implementation for FreakyAutoCompleteView..."

# Try locating the handler by filename
files=$(fd -e cs "FreakyAutoCompleteViewHandler.cs")
if [ -n "$files" ]; then
  echo "Found handler file(s) by name:"
  echo "$files"
  for f in $files; do
    echo -e "\n--- $f (first 200 lines) ---"
    sed -n '1,200p' "$f"
  done
  exit 0
fi

# Fallback: search for the class declaration
files=$(rg -l "class FreakyAutoCompleteViewHandler" -g '*.cs')
if [ -n "$files" ]; then
  echo "Found handler file(s) by class pattern:"
  echo "$files"
  for f in $files; do
    echo -e "\n--- $f (first 200 lines) ---"
    sed -n '1,200p' "$f"
  done
else
  echo "No Windows handler implementation found for FreakyAutoCompleteView."
fi

Length of output: 7955


Add missing property mappings in the Windows FreakyAutoCompleteViewHandler

The Windows handler currently only uses the default ViewMapper and doesn’t map any of the new control properties. You’ll need to update MAUI.FreakyControls/Platforms/Windows/FreakyAutoCompleteViewHandler.cs to include entries in its Mapper for all of the properties added in FreakyAutoCompleteView, for example:

• Text → MapText
• TextColor → MapTextColor
• Placeholder → MapPlaceholder
• PlaceholderColor → MapPlaceholderColor
• TextMemberPath → MapTextMemberPath
• DisplayMemberPath → MapDisplayMemberPath
• IsSuggestionListOpen → MapIsSuggestionListOpen
• Threshold → MapThreshold
• UpdateTextOnSelect → MapUpdateTextOnSelect
• ItemsSource → MapItemsSource
• ImageAlignment/ImageSource/ImageCommand/ImageCommandParameter/ImageHeight/ImagePadding/ImageWidth → MapImageSource
• HorizontalTextAlignment → MapHorizontalTextAlignment
• VerticalTextAlignment → MapVerticalTextAlignment
• FontFamily → MapFontFamily
• FontSize → MapFontSize
• FontAttributes → MapFontAttributes
• TextTransform → MapTextTransform

Make sure each MapXXX method is implemented (or exists) to update the AutoSuggestBox appropriately (either in the mapper itself or in ConnectHandler).

🧹 Nitpick comments (2)
MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/FreakyAutoCompleteView.cs (2)

13-18: Add XML documentation for new properties

Adding documentation comments would help developers understand the purpose and expected values for these new properties.

Consider adding XML documentation comments for each property:

+ /// <summary>
+ /// Gets or sets the horizontal text alignment.
+ /// </summary>
  public TextAlignment HorizontalTextAlignment { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

215-215: Remove trailing whitespace

There's a line with only whitespace characters.

-   
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f18b2a and 714f8d9.

📒 Files selected for processing (1)
  • MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/FreakyAutoCompleteView.cs (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-plugin-ci

Comment on lines +13 to +18
public TextAlignment HorizontalTextAlignment { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public TextAlignment VerticalTextAlignment { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string FontFamily { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public double FontSize { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public FontAttributes FontAttributes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public TextTransform TextTransform { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Convert new properties to bindable properties to maintain consistency and enable XAML binding

These new properties are implemented with NotImplementedException which will cause runtime errors if used. More importantly, they don't follow the pattern used by other properties in this class - they should be implemented as bindable properties to enable proper XAML data binding.

Consider implementing these as bindable properties similar to the existing properties in this class. For example:

- public TextAlignment HorizontalTextAlignment { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+ public TextAlignment HorizontalTextAlignment
+ {
+     get { return (TextAlignment)GetValue(HorizontalTextAlignmentProperty); }
+     set { SetValue(HorizontalTextAlignmentProperty, value); }
+ }
+ 
+ public static readonly BindableProperty HorizontalTextAlignmentProperty =
+     BindableProperty.Create(nameof(HorizontalTextAlignment), typeof(TextAlignment), typeof(FreakyAutoCompleteView), TextAlignment.Start, BindingMode.OneWay);

Apply the same pattern for all six new properties to maintain consistency with the rest of the class.


💡 Verification agent

🧩 Analysis chain

These placeholder properties will cause runtime errors

All six new properties throw NotImplementedException, which will cause the application to crash if any of these properties are accessed at runtime.


🏁 Script executed:

#!/bin/bash
# Check if these properties are referenced elsewhere in the codebase
echo "Checking for references to the new text formatting properties..."
rg -A 1 "HorizontalTextAlignment|VerticalTextAlignment|FontFamily|FontSize|FontAttributes|TextTransform" --glob "*.cs" --glob "*.xaml" | grep -v "NotImplementedException" || echo "No direct usage found"

Length of output: 74068


Implement proper BindableProperty-backed getters/setters for text‐formatting properties
The six new properties in FreakyAutoCompleteView.cs are currently throwing NotImplementedException, but they’re referenced throughout handlers and XAML (e.g. in MapHorizontalTextAlignment, MapFontSize, bindings in XAML). Any attempt to read or write them will crash at runtime.

Please replace the stubs at lines 13–18 of
MAUI.FreakyControls/MAUI.FreakyControls/FreakyAutoCompleteView/FreakyAutoCompleteView.cs
with BindableProperty definitions and getters/setters, for example:

-public TextAlignment HorizontalTextAlignment { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
+public static readonly BindableProperty HorizontalTextAlignmentProperty =
+    BindableProperty.Create(
+        nameof(HorizontalTextAlignment),
+        typeof(TextAlignment),
+        typeof(FreakyAutoCompleteView),
+        TextAlignment.Start);
+public TextAlignment HorizontalTextAlignment
+{
+    get => (TextAlignment)GetValue(HorizontalTextAlignmentProperty);
+    set => SetValue(HorizontalTextAlignmentProperty, value);
+}

Repeat for VerticalTextAlignment, FontFamily, FontSize, FontAttributes and TextTransform, matching defaults and types from other controls. This ensures bindings and handler mappings won’t trigger a crash.

@FreakyAli FreakyAli merged commit b577d4a into master Apr 28, 2025
4 checks passed
@FreakyAli FreakyAli deleted the r5-gh/fix/entry-imagesource branch April 28, 2025 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HandlerNotFoundException while debugging in Windows Machine mode

2 participants