From b08d6964c503086ee68ac7932f782716a0f90276 Mon Sep 17 00:00:00 2001 From: "Jeffrey T. Fritz" Date: Thu, 29 Jan 2026 15:10:22 -0500 Subject: [PATCH 1/2] Add documentation for HyperLink and Menu components; update navigation structure --- README.md | 4 +- .../HyperLink.md | 0 docs/{ => NavigationControls}/Menu.md | 51 +++++++++++++++++++ mkdocs.yml | 3 +- .../Menu/DynamicMenuStyleSample.razor | 3 +- .../wwwroot/js/Basepage.module.js | 13 ++++- 6 files changed, 69 insertions(+), 5 deletions(-) rename docs/{EditorControls => NavigationControls}/HyperLink.md (100%) rename docs/{ => NavigationControls}/Menu.md (87%) diff --git a/README.md b/README.md index 3e26a5e2e..617de49a9 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ There are a significant number of controls in ASP.NET Web Forms, and we will foc - [DropDownList](docs/EditorControls/DropDownList.md) - FileUpload - [HiddenField](docs/EditorControls/HiddenField.md) - - [HyperLink](docs/EditorControls/HyperLink.md) - [Image](docs/EditorControls/Image.md) - [ImageButton](docs/EditorControls/ImageButton.md) - ImageMap @@ -69,7 +68,8 @@ There are a significant number of controls in ASP.NET Web Forms, and we will foc - [RequiredFieldValidator](docs/ValidationControls/RequiredFieldValidator.md) - [ValidationSummary](docs/ValidationControls/ValidationSummary.md) - Navigation Controls - - [Menu](docs/Menu.md) + - [HyperLink](docs/NavigationControls/HyperLink.md) + - [Menu](docs/NavigationControls/Menu.md) - SiteMapPath - [TreeView](docs/NavigationControls/TreeView.md) - Login Controls diff --git a/docs/EditorControls/HyperLink.md b/docs/NavigationControls/HyperLink.md similarity index 100% rename from docs/EditorControls/HyperLink.md rename to docs/NavigationControls/HyperLink.md diff --git a/docs/Menu.md b/docs/NavigationControls/Menu.md similarity index 87% rename from docs/Menu.md rename to docs/NavigationControls/Menu.md index d88ad0ddc..65759410c 100644 --- a/docs/Menu.md +++ b/docs/NavigationControls/Menu.md @@ -341,5 +341,56 @@ The Menu component is meant to emulate the asp:Menu control in markup and is def ## Blazor Syntax +```html + + + + + + + + + + + + + + + + + + + + + + + + +``` + ##### [Back to top](#menu) diff --git a/mkdocs.yml b/mkdocs.yml index b34b898fe..9787c9f59 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -69,7 +69,6 @@ nav: - CheckBoxList: EditorControls/CheckBoxList.md - DropDownList: EditorControls/DropDownList.md - HiddenField: EditorControls/HiddenField.md - - HyperLink: EditorControls/HyperLink.md - Image: EditorControls/Image.md - ImageButton: EditorControls/ImageButton.md - Label: EditorControls/Label.md @@ -95,6 +94,8 @@ nav: - RequiredFieldValidator: ValidationControls/RequiredFieldValidator.md - ValidationSummary: ValidationControls/ValidationSummary.md - Navigation Controls: + - HyperLink: NavigationControls/HyperLink.md + - Menu: NavigationControls/Menu.md - TreeView: NavigationControls/TreeView.md - Login Controls: - Login: LoginControls/Login.md diff --git a/samples/AfterBlazorServerSide/Pages/ControlSamples/Menu/DynamicMenuStyleSample.razor b/samples/AfterBlazorServerSide/Pages/ControlSamples/Menu/DynamicMenuStyleSample.razor index fb4f619a7..53086ccb6 100644 --- a/samples/AfterBlazorServerSide/Pages/ControlSamples/Menu/DynamicMenuStyleSample.razor +++ b/samples/AfterBlazorServerSide/Pages/ControlSamples/Menu/DynamicMenuStyleSample.razor @@ -1,4 +1,5 @@ -@using static BlazorWebFormsComponents.WebColor +@page "/ControlSamples/Menu/DynamicMenuStyleSample" +@using static BlazorWebFormsComponents.WebColor @using static BlazorWebFormsComponents.Enums.BorderStyle

DynamicMenuStyle Sample

diff --git a/src/BlazorWebFormsComponents/wwwroot/js/Basepage.module.js b/src/BlazorWebFormsComponents/wwwroot/js/Basepage.module.js index cc63f68a6..f7eefa0d5 100644 --- a/src/BlazorWebFormsComponents/wwwroot/js/Basepage.module.js +++ b/src/BlazorWebFormsComponents/wwwroot/js/Basepage.module.js @@ -14,6 +14,16 @@ export function onAfterRender() { formatClientClick(); } +export function addScriptElement(location, callback) { + var el = document.createElement("script"); + el.setAttribute("src", location); + document.head.appendChild(el); + + if (callback != null) { + el.addEventListener("load", function () { eval(callback); }); + } +} + function formatClientClick() { var elementsToReplace = document.querySelectorAll("*[onclientclick]"); for (var el of elementsToReplace) { @@ -31,6 +41,7 @@ if (typeof window !== 'undefined') { window.bwfc.Page = { setTitle, getTitle, - OnAfterRender: onAfterRender + OnAfterRender: onAfterRender, + AddScriptElement: addScriptElement }; } From 287fbcdb9426959432de802dd89fa1374d897d94 Mon Sep 17 00:00:00 2001 From: "Jeffrey T. Fritz" Date: Thu, 29 Jan 2026 15:20:28 -0500 Subject: [PATCH 2/2] Enhance documentation for Button, HiddenField, and Image components; add usage examples and clarify features Fixes #228 Fixes #219 Fixes #217 --- docs/EditorControls/Button.md | 237 +++++++++++++++++- docs/EditorControls/HiddenField.md | 94 ++++++- docs/EditorControls/Image.md | 190 +++++++++++++- .../Components/Layout/NavMenu.razor | 2 + .../Components/Pages/ComponentList.razor | 2 + .../ControlSamples/HiddenField/Index.razor | 86 +++++++ .../Pages/ControlSamples/Image/Index.razor | 112 +++++++++ 7 files changed, 700 insertions(+), 23 deletions(-) create mode 100644 samples/AfterBlazorServerSide/Components/Pages/ControlSamples/HiddenField/Index.razor create mode 100644 samples/AfterBlazorServerSide/Components/Pages/ControlSamples/Image/Index.razor diff --git a/docs/EditorControls/Button.md b/docs/EditorControls/Button.md index acf38d834..9fa39b22c 100644 --- a/docs/EditorControls/Button.md +++ b/docs/EditorControls/Button.md @@ -1,19 +1,37 @@ -It may seem strange that we have a Button component when there already is an HTML button and Blazor has features that enable C# interactions with that button, but we need to activate other features that were once present in Web Forms. Original Web Forms documentation is at: https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.button?view=netframework-4.8 +# Button -## Blazor Features Supported +The **Button** component displays a push button control that allows users to trigger actions. It may seem strange that we have a Button component when there already is an HTML button and Blazor has features that enable C# interactions with that button, but we need to activate other features that were once present in Web Forms, such as `OnCommand` event bubbling, `OnClientClick` JavaScript execution, and `CausesValidation` support. -- OnClick event handler -- OnClientClick JavaScript pointer -- OnCommand event handler with event bubbling -- Button Style attributes and CssClass formatting -- CausesValidation will control whether Form validation is triggered on click +Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.button?view=netframework-4.8 -## WebForms Features Not Supported +## Features Supported in Blazor -- PostBackUrl is not supported as you will be triggering Button click events on the same page -- UseSubmitBehavior is not supported as Blazor buttons trigger click events and you can inspect the Form regardless +- `Text` - the text displayed on the button +- `OnClick` - event handler triggered when button is clicked +- `OnClientClick` - JavaScript code to execute on client-side click +- `OnCommand` - event handler with event bubbling, receives `CommandEventArgs` with `CommandName` and `CommandArgument` +- `CommandName` - the command name passed to `OnCommand` event +- `CommandArgument` - the command argument passed to `OnCommand` event +- `CausesValidation` - controls whether form validation is triggered on click (default: `true`) +- `Enabled` - enables or disables the button +- `Visible` - controls button visibility +- `ToolTip` - tooltip text displayed on hover +- All style properties (`BackColor`, `ForeColor`, `BorderColor`, `BorderStyle`, `BorderWidth`, `CssClass`, `Width`, `Height`, `Font`) -## WebForms Syntax +### Blazor Notes + +- The `OnCommand` event uses a `CommandEventArgs` class that contains `CommandName` and `CommandArgument` properties +- When `CommandName` is set, clicking the button triggers `OnCommand` instead of `OnClick` +- Event bubbling is supported for container components that need to handle commands from child buttons + +## Web Forms Features NOT Supported + +- **PostBackUrl** - Not supported; Blazor uses component events instead of postbacks to different pages +- **UseSubmitBehavior** - Not supported; Blazor buttons trigger click events and you can inspect the form regardless +- **ValidationGroup** - Not yet implemented; use EditForm validation instead +- **AccessKey** - Use HTML `accesskey` attribute directly if needed + +## Web Forms Declarative Syntax ```html ``` + +## Blazor Razor Syntax + +### Basic Button with Click Event + +```razor + +``` + +**Styled Button Input:** +```razor + +``` + +## Migration Notes + +When migrating from Web Forms to Blazor: + +1. **Remove `asp:` prefix** - Change `` to ` + +@code { + private bool showBanner = true; + + void ToggleBanner() + { + showBanner = !showBanner; + } +} +``` + +### Text Wrapping with Aligned Image + +```razor +@using BlazorWebFormsComponents.Enums + + + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. + This text wraps around the left-aligned image. The ImageAlign + property allows you to control how content flows around the image.

+ +
+``` + +## See Also + +- [ImageButton](ImageButton.md) - A clickable image that acts as a button +- [HyperLink](../NavigationControls/HyperLink.md) - Wrap an Image in a HyperLink for clickable images +- [Live Demo](https://blazorwebformscomponents.azurewebsites.net/ControlSamples/Image) - Interactive Image samples diff --git a/samples/AfterBlazorServerSide/Components/Layout/NavMenu.razor b/samples/AfterBlazorServerSide/Components/Layout/NavMenu.razor index 7dbd1ab3e..02baa5f73 100644 --- a/samples/AfterBlazorServerSide/Components/Layout/NavMenu.razor +++ b/samples/AfterBlazorServerSide/Components/Layout/NavMenu.razor @@ -24,6 +24,8 @@ + + diff --git a/samples/AfterBlazorServerSide/Components/Pages/ComponentList.razor b/samples/AfterBlazorServerSide/Components/Pages/ComponentList.razor index 5a212a27c..922c4b28f 100644 --- a/samples/AfterBlazorServerSide/Components/Pages/ComponentList.razor +++ b/samples/AfterBlazorServerSide/Components/Pages/ComponentList.razor @@ -6,6 +6,8 @@
  • Button
  • CheckBox
  • DropDownList
  • +
  • HiddenField
  • +
  • Image
  • HyperLink
  • LinkButton
  • Literal
  • diff --git a/samples/AfterBlazorServerSide/Components/Pages/ControlSamples/HiddenField/Index.razor b/samples/AfterBlazorServerSide/Components/Pages/ControlSamples/HiddenField/Index.razor new file mode 100644 index 000000000..66211f39e --- /dev/null +++ b/samples/AfterBlazorServerSide/Components/Pages/ControlSamples/HiddenField/Index.razor @@ -0,0 +1,86 @@ +@page "/ControlSamples/HiddenField" + +HiddenField Sample + +

    HiddenField - Basic Usage

    + +

    The HiddenField component stores a non-displayed value. While the field is not visible to users, the value is accessible to both server-side code and JavaScript.

    + +
    +

    Demo

    + + + +

    Current hidden value: @HiddenValue

    + +
    + + +
    + +
    + +
    + +

    Source Code

    + +
    @@page "/ControlSamples/HiddenField"
    +
    +<HiddenField ID="myHiddenField" Value="@@HiddenValue" OnValueChanged="HandleValueChanged" />
    +
    +<p><strong>Current hidden value:</strong> @@HiddenValue</p>
    +
    +<div class="mb-3">
    +    <label class="form-label">Update hidden field value:</label>
    +    <input type="text" class="form-control" @@bind="NewValue" />
    +</div>
    +
    +<Button Text="Update Hidden Field" OnClick="UpdateHiddenValue" />
    +
    +@@code {
    +    private string HiddenValue = "initial-secret-value";
    +    private string NewValue = "";
    +    private string Message = "";
    +
    +    private void UpdateHiddenValue()
    +    {
    +        if (!string.IsNullOrEmpty(NewValue))
    +        {
    +            HiddenValue = NewValue;
    +            Message = $"Hidden field updated to: {HiddenValue}";
    +            NewValue = "";
    +        }
    +    }
    +
    +    private void HandleValueChanged(EventArgs e)
    +    {
    +        Message = "Value changed event triggered!";
    +    }
    +}
    + +@code { + private string HiddenValue = "initial-secret-value"; + private string NewValue = ""; + private string Message = ""; + + private void UpdateHiddenValue() + { + if (!string.IsNullOrEmpty(NewValue)) + { + HiddenValue = NewValue; + Message = $"Hidden field updated to: {HiddenValue}"; + NewValue = ""; + } + } + + private void HandleValueChanged(EventArgs e) + { + Message = "Value changed event triggered!"; + } +} diff --git a/samples/AfterBlazorServerSide/Components/Pages/ControlSamples/Image/Index.razor b/samples/AfterBlazorServerSide/Components/Pages/ControlSamples/Image/Index.razor new file mode 100644 index 000000000..41f97b15c --- /dev/null +++ b/samples/AfterBlazorServerSide/Components/Pages/ControlSamples/Image/Index.razor @@ -0,0 +1,112 @@ +@page "/ControlSamples/Image" +@using BlazorWebFormsComponents +@using BlazorWebFormsComponents.Enums + +Image Sample + +

    Image - Basic Usage

    + +

    The Image component displays an image on a web page, emulating the ASP.NET Web Forms Image control.

    + +
    + +

    Basic Image

    +

    A simple image with alternate text:

    + +
    + +
    + +

    Code:

    +
    <Image ImageUrl="https://via.placeholder.com/150x100" 
    +       AlternateText="Sample placeholder image" />
    + +
    + +

    Image with Tooltip

    +

    Hover over the image to see the tooltip:

    + +
    + +
    + +

    Code:

    +
    <Image ImageUrl="https://via.placeholder.com/150x100/0066cc/ffffff?text=Hover+Me" 
    +       AlternateText="Image with tooltip"
    +       ToolTip="This is a tooltip displayed on hover" />
    + +
    + +

    Image Alignment

    +

    Images can be aligned using the ImageAlign property:

    + +
    + +

    This text flows around the left-aligned image. The ImageAlign property + controls how content flows around the image, similar to the CSS float property. + This is useful when migrating Web Forms applications that rely on this behavior.

    +
    + +

    Code:

    +
    <Image ImageUrl="https://via.placeholder.com/80x80" 
    +       AlternateText="Left aligned image"
    +       ImageAlign="ImageAlign.Left" />
    +<p>This text flows around the left-aligned image...</p>
    + +
    + +

    Dynamic Image with Visibility Toggle

    +

    Click the button to toggle image visibility:

    + +
    + + +
    + +
    +
    + +

    Code:

    +
    <button @@onclick="ToggleVisibility">Toggle</button>
    +<Image ImageUrl="..." AlternateText="Toggleable image" Visible="@@isVisible" />
    +
    +@@code {
    +    private bool isVisible = true;
    +    
    +    void ToggleVisibility()
    +    {
    +        isVisible = !isVisible;
    +    }
    +}
    + +
    + +

    Decorative Image (Empty Alt Text)

    +

    For decorative images that don't convey content, use GenerateEmptyAlternateText:

    + +
    + +

    The decorative separator above has an empty alt attribute for accessibility compliance.

    +
    + +

    Code:

    +
    <Image ImageUrl="..." GenerateEmptyAlternateText="true" />
    + +@code { + private bool isVisible = true; + + void ToggleVisibility() + { + isVisible = !isVisible; + } +}