diff --git a/MAUI/AI-Coding-Assistant/mcp-server.md b/MAUI/AI-Coding-Assistant/mcp-server.md new file mode 100644 index 0000000000..c0a3108994 --- /dev/null +++ b/MAUI/AI-Coding-Assistant/mcp-server.md @@ -0,0 +1,236 @@ +--- +layout: post +title: SyncfusionMAUIAssistant MCP Server | Syncfusion +description: Learn how to configure and use SyncfusionMAUIAssistant MCP server for intelligent code generation, documentation, and troubleshooting in .NET MAUI apps. +platform: MAUI +control: Getting started with SyncfusionMAUIAssistant MCP Server +documentation: ug +--- + +# SyncfusionMAUIAssistant MCP Server + +## Overview + +The `SyncfusionMAUIAssistant` is a specialized [Model Context Protocol (MCP)](https://modelcontextprotocol.io/docs/getting-started/intro) server that provides intelligent assistance for developers using Syncfusion's .NET MAUI component libraries. This tool seamlessly integrates with compatible [MCP clients](https://modelcontextprotocol.io/clients) to enhance your development workflow when building .NET MAUI applications with Syncfusion® components. + +### Key Benefits + +* Intelligent code generation for Syncfusion® .NET MAUI components. +* Detailed component documentation and usage examples. +* Troubleshooting assistance for common integration challenges. + +## Prerequisites + +Before using `SyncfusionMAUIAssistant`, ensure you have: + +* Required [node](https://nodejs.org/en/) version >= 18 +* A [compatible MCP client](https://modelcontextprotocol.io/clients) (VS Code with GitHub Copilot, [Syncfusion® CodeStudio](https://www.syncfusion.com/code-studio/), etc.) +* An active Syncfusion® license (any of the following): + - [Commercial License](https://www.syncfusion.com/sales/unlimitedlicense) + - [Free Community License](https://www.syncfusion.com/products/communitylicense) + - [Free Trial](https://www.syncfusion.com/account/manage-trials/start-trials) +* An active [API KEY](https://syncfusion.com/account/api-key) + +## Unlimited Access + +Syncfusion® offers unlimited access to this MCP server. There are no restrictions on: + +* Number of requests +* Components usage +* Query types +* Usage duration + +This ensures users can fully leverage Syncfusion® components to enhance their development experience without limitations. + +## Installation and setup + +Before you can invoke the `SyncfusionMAUIAssistant` MCP server, you need to configure your MCP client with these core settings. The **Generic MCP Server Settings** shown below are identical across all clients: + +### Generic MCP Server Settings + +- **npm package name**: `@syncfusion/maui-assistant` +- **Type**: stdio (standard input/output transport) +- **Command**: npx +- **Arguments**: -y +- **Server name**: syncfusionMAUIAssistant + +You need to add your [Syncfusion API key](https://syncfusion.com/account/api-key) as an env parameter in the configuration file: + +```json +"env": { + "Syncfusion_API_Key": "YOUR_API_KEY" +} +``` + +Below are setup instructions for popular MCP clients: + +### Syncfusion® Code Studio + +* In [Code Studio](https://www.syncfusion.com/code-studio/), open MCP Marketplace and navigate to the `Custom Servers` tab. +* Enter the Server Name as `maui-mcp`, choose Server Type as npm package, and set the NPM Package name to `@syncfusion/maui-assistant`. +* Add an environment variable as `Syncfusion_API_Key` and value as your [Syncfusion API key](https://syncfusion.com/account/api-key), then click **Install Server**. +* Once installed, the server will appear in the User Installed Server list, and will be added to the **config.yaml** file. +* The server is now ready for use in Code Studio. For more details, refer to the [Code Studio documentation](https://help.syncfusion.com/code-studio/reference/configure-properties/mcp/customservers#npm-server). + +### Visual Studio Code (GitHub Copilot MCP) + +* To configure an MCP server for a specific workspace, you can create a `.vscode/mcp.json` file in your workspace folder. + +```json +{ + "servers": { + "syncfusion-maui-assistant": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@syncfusion/maui-assistant@latest" + ], + "env": { + "Syncfusion_API_Key": "YOUR_API_KEY" + } + } + } +} +``` + +* After updating the configuration in settings.json, you'll notice a "Start" option at the top of the config. This allows you to easily start the `SyncfusionMauiAssistant` server directly from the settings interface without additional commands. + +* Confirm the server is active by checking for a message like: `SyncfusionMAUIAssistant is running...` in the output. + +* For additional guidance, refer to the [VS Code documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers#_add-an-mcp-server). + +### Visual Studio (GitHub Copilot MCP) + +* To configure an MCP server for a specific workspace, you can create a `.vs/mcp.json` file in your workspace folder. + +```json +{ + "servers": { + "syncfusion-maui-assistant": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@syncfusion/maui-assistant@latest" + ], + "env": { + "Syncfusion_API_Key": "YOUR_API_KEY" + } + } + } +} +``` + +* After updating the mcp.json configuration, open the GitHub Copilot Chat window. Click the Ask arrow, then select Agent. +* Select the `SyncfusionMAUIAssistant`from the tools section. +* For more details, refer to the official [Visual Studio documentation](https://learn.microsoft.com/en-us/visualstudio/ide/mcp-servers?view=vs-2022). + +### Cursor + +To configure an MCP server for a specific workspace, you can create a .cursor/mcp.json file in your workspace folder. + +```json +{ + "mcpServers": { + "syncfusion-maui-assistant": { + "type": "stdio", + "command": "npx", + "args": [ + "-y", + "@syncfusion/maui-assistant@latest" + ], + "env": { + "Syncfusion_API_Key": "YOUR_API_KEY" + } + } + } +} +``` +For more details, refer to the [Cursor documentation](https://cursor.com/docs/context/mcp#using-mcp-json). + +### JetBrains IDEs + +* Go to Settings -> Tools -> AI Assistant -> Model Context Protocol (MCP). +* Click + Add to add a new MCP server configuration. +* In the New MCP Server dialog, switch the dropdown as `As JSON` and add the following config: + +```json +{ + "mcpServers": { + "syncfusion-maui-assistant": { + "command": "npx", + "args": [ + "-y", + "@syncfusion/maui-assistant@latest" + ], + "env": { + "Syncfusion_API_Key": "YOUR_API_KEY" + } + } + } +} +``` + +* Click OK and Apply. + +For further assistance, see the [JetBrains documentation](https://www.jetbrains.com/help/ai-assistant/mcp.html#connect-to-an-mcp-server). + +> For more detailed information about configuring MCP servers in various clients, refer to the official documentations, e.g., [Windsurf](https://docs.windsurf.com/windsurf/cascade/mcp#mcp-config-json) + +## Usage + +To activate the SyncfusionMAUIAssistant MCP server: + +1. Start your prompt with one of the following: + * 'SyncfusionMAUIAssistant' + * '/syncfusion-maui-assistant' + * '/syncfusion-maui' + * '@syncfusion-maui' + * '@ask_syncfusion_maui' + * 'maui' + + In VS Code, you can also use #SyncfusionMAUIAssistant for direct invocation. + +2. Grant permission for the server to run (for the session, workspace, or always). +3. For best results, start a new chat for each new topic to maintain clean context. + +### Mode availability + +Syncfusion® MCP Servers provide full access to all AI interaction modes — Ask/Chat, Edit, and Agent — across supported MCP clients. + +### Best Practices for Effective Usage + +1. `Be specific`: Mention both platform and component (e.g., "How do I create a Syncfusion MAUI DataGrid with paging and filtering?"). +2. `Provide context`: Include details about your use case for more targeted solutions. +3. `Use descriptive queries`: Avoid vague questions that lack necessary context. +4. `Start fresh for new topics`: Begin a new chat session when switching components or topics. + +### Example Queries + +Here are some effective ways to use `SyncfusionMAUIAssistant`: + + * "Create a Syncfusion .NET MAUI DataGrid component with paging, sorting and filtering" + * "How do I implement data binding with Syncfusion .NET MAUI Scheduler?" + +## Troubleshooting + +If you encounter issues: + + * Verify your API key is correctly configured. + * Ensure the MCP server is enabled in your client's tools selection. + * Check that you're using a compatible MCP client version. + * Try restarting your development environment. + +## Support + +Product support is available through the following mediums. + +* [Support ticket](https://support.syncfusion.com/support/tickets/create) - Guaranteed Response in 24 hours \| Unlimited tickets \| Holiday support +* [Community forum](https://www.syncfusion.com/forums/maui) +* [Request feature or report bug](https://www.syncfusion.com/feedback/maui) +* Live chat + +## See also + +* [Syncfusion .NET MAUI Documentation](https://help.syncfusion.com/maui/introduction/overview) diff --git a/MAUI/AI-Coding-Assistant/overview.md b/MAUI/AI-Coding-Assistant/overview.md new file mode 100644 index 0000000000..11107ac10c --- /dev/null +++ b/MAUI/AI-Coding-Assistant/overview.md @@ -0,0 +1,70 @@ +--- +layout: post +title: Syncfusion AI Coding Assistant Overview | Syncfusion +description: Learn how Syncfusion AI Coding Assistant boost .NET MAUI productivity by generating accurate code snippets, configuration examples, and contextual guidance. +platform: MAUI +control: Syncfusion AI Coding Assistant Overview. +documentation: ug +--- + +# Syncfusion® AI Coding Assistant Overview + +The **Syncfusion® AI Coding Assistant** are designed to streamline your development workflow when building MAUI applications with Syncfusion® components. It uses contextual knowledge of the Syncfusion® component library to generate accurate code snippets, configuration examples, and guided explanations—minimizing documentation searches and maximizing productivity. + +AI Coding Assistant: + +* **The SyncfusionMAUIAssistant MCP Server** + Processes advanced prompts and returns tailored code suggestions via [MCP-compatible clients](https://modelcontextprotocol.io/clients). + + +## Getting Started + +To use the AI Coding Assistant, you need: + +* A [Syncfusion® user account](https://www.syncfusion.com/account) +* An active Syncfusion® license (any of the following): + - [Commercial License](https://www.syncfusion.com/sales/unlimitedlicense) + - [Free Community License](https://www.syncfusion.com/products/communitylicense) + - [Free Trial](https://www.syncfusion.com/account/manage-trials/start-trials) +* An active [API KEY](https://syncfusion.com/account/api-key) +* A [MAUI application that includes Syncfusion MAUI](https://help.syncfusion.com/maui/introduction/overview) + +## Unlimited Access + +Syncfusion® offers unlimited access to the AI Coding Assistant, with no limitations on: + +* Number of requests +* Components usage +* Query types +* Usage duration + +This ensures users can fully leverage Syncfusion® components to enhance their development experience without limitations. + +## Best Practices + +* Initial Setup: Use the tools to quickly add and configure Syncfusion® components in your MAUI application. +* Feature Tuning: Enable or disable component features through prompt-based configuration for tailored functionality. +* Data Binding: Generate sample data for testing and prototyping. Avoid using sensitive or production data to ensure security. +* Step-by-step explanations: Use annotated code to understand component behavior. Note that the level of detail may vary depending on the tool, mode, and AI model used. Refer to the [Syncfusion® MAUI Documentation](https://help.syncfusion.com/maui/introduction/overview) for in-depth information. +* Troubleshooting: Resolve common issues with AI-generated suggestions. For complex problems, refer to [documentation](https://help.syncfusion.com/maui/introduction/overview) or [support](https://support.syncfusion.com/support/tickets/create). + +> Always check AI-generated content and code for accuracy before using it. + +## Recommendations + +* Session Management: Start new sessions when switching tasks to ensure prompt relevance and maintain content focus. +* Model Compatibility: For optimal performance, use the tools with advanced AI models such as GPT-5 or Claude Sonnet 4. + +## Privacy & Data Handling + +The Syncfusion® AI Coding Assistant is designed with privacy in mind: + +* The tools do not access your project files or workspace directly. +* User prompts are not stored by any of the tools or used for any other purpose. +* Prompts are not used to train Syncfusion® models. +* The assistant generates context, while the final output is handled by your selected AI model. + +## See also + +* Add the `SyncfusionMAUIAssistant MCP Server` to an MCP-enabled client +* [Syncfusion® MAUI Documentation](https://help.syncfusion.com/maui/introduction) diff --git a/MAUI/DataGrid/FilterRow.md b/MAUI/DataGrid/FilterRow.md new file mode 100644 index 0000000000..a8638ced6a --- /dev/null +++ b/MAUI/DataGrid/FilterRow.md @@ -0,0 +1,569 @@ +--- +layout: post +title: Filter Row in .NET MAUI DataGrid | Syncfusion +description: Learn here all about FilterRow support in Syncfusion® .NET MAUI DataGrid (SfDataGrid) control and more. +platform: MAUI +control: SfDataGrid +documentation: ug +keywords : maui datagrid, maui grid, grid maui, maui gridview, grid in maui, .net maui datagrid, .net maui grid, .net grid maui, .net maui filterrow, maui filterrow +--- + +# Filter Row in MAUI DataGrid (SfDataGrid) + +The [SfDataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html) includes a built-in Filter Row designed for efficient record filtering. You can enable the FilterRow by specifying the position where it should be displayed by setting [SfDataGrid.FilterRowPosition]() property. + +{% tabs %} +{% highlight XAML %} + +{% endhighlight %} +{% highlight c# %} +this.dataGrid.FilterRowPosition = DataGridFilterRowPosition.FixedTop; +{% endhighlight %} +{% endtabs %} + +MAUI DataGrid with Filter Row + +Retrieve the row index of the FilterRow using the [SfDataGrid.GetFilterRowIndex]() method. + +{% tabs %} +{% highlight c# %} +int filterRowIndex = this.dataGrid.GetFilterRowIndex(); +{% endhighlight %} +{% endtabs %} + +Verify if a given row index corresponds to the FilterRow by utilizing the [SfDataGrid.IsFilterRowIndex]() helper method. + +{% tabs %} +{% highlight c# %} +bool isFilterRowIndex = this.dataGrid.IsFilterRowIndex(1); +{% endhighlight %} +{% endtabs %} + +## Built-in editors + +The FilterRow automatically initializes editors that correspond to the underlying property type, simplifying data filtering. Customize these default editors by setting the `DataGridColumn.FilterRowEditorType` property. + +{% tabs %} +{% highlight XAML %} + + + +{% endhighlight %} +{% highlight c# %} + +this.dataGrid.Columns[2].FilterRowEditorType = "MultiSelectComboBox"; + +{% endhighlight %} +{% endtabs %} + +MAUI DataGrid Filter Row Cell with MultiSelect ComboBox + +Below are the built-in FilterRow editor types supported in SfDataGrid. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FilterRowEditor Type Editor Control Renderer Description
TextBox SfDataGridEntry DataGridFilterRowTextBoxRenderer Enables filtering for string data.
Numeric SfNumericEntry DataGridFilterRowNumericBoxRenderer Facilitates filtering for numeric data.
ComboBox SfComboBox DataGridFilterRowComboBoxRenderer Allows selection of a single value for filtering from a dropdown.
MultiSelectComboBox SfComboBox DataGridFilterRowMultiSelectRenderer Permits selection of multiple values for filtering from a dropdown.
CheckBox SfCheckBox DataGridFilterRowCheckBoxRenderer Supports filtering of Boolean data.
DateTime DatePicker DataGridFilterRowDateRenderer Provides filtering capabilities for DateTime data.
+ +## Filter options + +The FilterRowCell presents filter conditions in a dropdown menu, categorized by editor type, allowing for easy switching between conditions to refine data. To disable these filter options, set the `DataGridColumn.FilterRowOptionsVisibility` property. + +{% tabs %} +{% highlight XAML %} + + + +{% endhighlight %} +{% highlight c# %} + +this.dataGrid.Columns[0].FilterRowOptionsVisibility = false; + +{% endhighlight %} +{% endtabs %} + +MAUI DataGrid with Filter Row + +Below are the filter conditions supported by different filter row editors in SfDataGrid. + + + + + + + + + + + + + + + + + + + + + + + +
Numeric Editor TextBox Editor DateTime Editor CheckBox Editor ComboBox, MultiSelectComboBox Editor
The numeric editor is utilized in DataGridFilterRowCell when integer, double, short, decimal, byte, or long data types are bound to the DataGridColumn.FilterRowEditorType. The text editor is employed in DataGridFilterRowCell for string-bound DataGridColumn values or dynamic item sources. For DataGridColumn entries with datetime data types, the datetime editor is loaded into the DataGridFilterRowCell. When a boolean type is bound to the DataGridColumn, the checkbox editor is automatically loaded in the DataGridFilterRowCell. To use comboBox and MultiSelectComboBox editors, the FilterRowEditorType property must be explicitly set.
The default numeric filter condition is Equals. Additional available conditions include: +
    +
  1. Equals
  2. +
  3. Does Not Equal
  4. +
  5. Null
  6. +
  7. Not Null
  8. +
  9. Less Than
  10. +
  11. Less Than or Equal
  12. +
  13. Greater Than
  14. +
  15. Greater Than or Equal
  16. +
The default text filter condition is Contains. Other available conditions include: +
    +
  1. Equals
  2. +
  3. Does Not Equal
  4. +
  5. Null
  6. +
  7. Not Null
  8. +
  9. Begins With
  10. +
  11. Does Not Begin With
  12. +
  13. Ends With
  14. +
  15. Does Not End With
  16. +
  17. Contains
  18. +
  19. Does Not Contain
  20. +
  21. Empty
  22. +
  23. Not Empty
  24. +
The default DateTime filter condition is Equal. Additional conditions provided are: +
    +
  1. Equals
  2. +
  3. Does Not Equal
  4. +
  5. Null
  6. +
  7. Not Null
  8. +
  9. Before
  10. +
  11. Before or Equal
  12. +
  13. After
  14. +
  15. After or Equal
  16. +
For checkbox values, the Equals filter condition is always applied.
+ +Modify the default FilterRow condition for any specific column using the `DataGridColumn.FilterRowCondition` property. + +{% tabs %} +{% highlight XAML %} + + + + +{% endhighlight %} +{% highlight c# %} + +this.dataGrid.Columns[0].FilterRowCondition = FilterRowCondition.LessThan; + +{% endhighlight %} +{% endtabs %} + + +## Filtering null values + +Control the inclusion of null values in filtering by configuring the `DataGridColumn.AllowBlankFilters` property, which is true by default. When active, filter options display `Null` and `Not Null` choices, and ComboBox editors include a `Blanks` option for null value filtering. + +{% tabs %} +{% highlight XAML %} + +{% endhighlight %} +{% highlight c# %} + +this.dataGrid.Columns[0].AllowBlankFilters = false; + +{% endhighlight %} +{% endtabs %} + +Filter Row without Null option in MAUI DataGrid + +{% tabs %} +{% highlight XAML %} + +{% endhighlight %} +{% highlight c# %} + +this.dataGrid.Columns[0].AllowBlankFilters = true; + +{% endhighlight %} +{% endtabs %} + +Filter Row with Null option in MAUI DataGrid + +## Instant filtering +Filters are typically applied to columns upon cell navigation or pressing the Enter key. However, by setting [DataGridColumn.ImmediateUpdateColumnFilter]() to `true`, you can enable instant filtering as you type within the editor. +{% tabs %} +{% highlight xaml %} + +{% endhighlight %} +{% highlight c# %} +this.dataGrid.Columns[2].ImmediateUpdateColumnFilter = true; +{% endhighlight %} +{% endtabs %} + + +## Disable filtering for a particular cell +While filter row cells are editable by default for record filtering, you can prevent editing for a specific cell using the [CurrentCellBeginEdit](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html#Syncfusion_Maui_DataGrid_SfDataGrid_CurrentCellBeginEdit) event. +{% tabs %} +{% highlight c# %} +this.dataGrid.CurrentCellBeginEdit += DataGrid_CurrentCellBeginEdit; + +private void DataGrid_CurrentCellBeginEdit(object? sender, DataGridCurrentCellBeginEditEventArgs e) + { + if (e?.Column?.MappingName == "CustomerID" && dataGrid.IsFilterRowIndex(e.RowColumnIndex.RowIndex)) + e.Cancel = true; + } +{% endhighlight %} +{% endtabs %} + +## Styling + +### Apply default style + +You can customize the basic styling of the FilterRow in SfDataGrid using the DefaultStyle property. This approach allows you to modify attributes such as `FilterRowFontAttributes`, `FilterIconHoverBackground`, `FilterRowBackground`, `FilterRowFontFamily`, `FilterRowFontSize`, and `FilterRowTextColor`. + +{% tabs %} +{% highlight xaml %} + + + + +{% endhighlight %} +{% endtabs %} + +### Filter row style +Customize the appearance of the filter row by defining a style with TargetType [DataGridFilterRowView]. +{% tabs %} +{% highlight xaml %} + + + +{% endhighlight %} +{% endtabs %} + +Customizing Filter Row Style in MAUI DataGrid + +### Customizing filter row cell +Further customize the filter row cell's appearance through the `FilterRowCellStyle` property. + +{% tabs %} +{% highlight xaml %} + + + + + + + +{% endhighlight %} +{% endtabs %} + +Customizing Filter Row Cell Style in MAUI DataGrid + +## Customizing filter row editors + +### Customizing the filter row renderer + +[SfDataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html) allows you to customize the filter row renderer behavior by overriding the corresponding renderer associated with the filter row cell. Each renderer have a set of virtual methods for handling the filter row behaviors. You can also create new renderers instead of overriding the existing renderer. +You can customize the default TextBox editor behavior by overriding `DataGridFilterRowTextBoxRenderer` class and add the custom renderer to `FilterRowCellRenderers`. + +{% tabs %} +{% highlight xaml %} + +{% endhighlight %} +{% highlight c# %} + public MainPage() + { + InitializeComponent(); + + this.dataGrid.FilterRowCellRenderers.Add("CustomTextBox", new CustomDataGridFilterRowTextBoxRenderer()); + } + + public class CustomDataGridFilterRowTextBoxRenderer : DataGridFilterRowTextBoxRenderer + { + public CustomDataGridFilterRowTextBoxRenderer(): base() + { + } + } +{% endhighlight %} +{% endtabs %} + +### Filter based on numeric interval by using the multi select combobox filter + +By default, columns support filtering multiple values using the MultiSelectComboBox filter editor type. To filter data based on a range of numeric values, you can override the PopulateComboBoxItems and GetFilterPredicates methods within the DataGridFilterRowComboBoxRenderer class, as demonstrated in the code below. + +{% tabs %} +{% highlight xaml %} + +{% endhighlight %} +{% highlight c# %} + public MainPage() + { + InitializeComponent(); + + this.dataGrid.FilterRowCellRenderers.Add("CustomComboBox", new CustomDataGridFilterRowComboBoxRenderer()); + } + + public class CustomDataGridFilterRowComboBoxRenderer : DataGridFilterRowComboBoxRenderer , INotifyPropertyChanged +{ + private List? numericComboBoxItems; + + public event PropertyChangedEventHandler? PropertyChanged; + + private string selectedText = string.Empty; + + public CustomDataGridFilterRowComboBoxRenderer() + { + SetNumericComboBoxItemsList(); + } + + /// + /// Generate the Items for NumericComboBox + /// + /// + + public void SetNumericComboBoxItemsList() + { + numericComboBoxItems = new List(); + numericComboBoxItems.Add("Between 1 and 5"); + numericComboBoxItems.Add("Between 5 and 10"); + numericComboBoxItems.Add("Between 10 and 20"); + numericComboBoxItems.Add("Between 1000 and 1005"); + numericComboBoxItems.Add(">40"); + } + + /// + /// Gets filter predicates based on selected values. + /// + public override List GetFilterPredicates(object? filterValue) + { + var predicates = new List(); + var filterMode = ColumnFilter.Value; + + if (filterValue == null) + return predicates; + + if (filterValue is string text) + { + selectedText = text; + + text = text.Trim(); + + if (text.StartsWith("Between", StringComparison.OrdinalIgnoreCase)) + { + var remainder = text.Substring(7).Trim(); + + var parts = remainder.Split(new[] { "and" }, StringSplitOptions.RemoveEmptyEntries); + + if (parts.Length == 2 && TryParseDouble(parts[0], out var minVal) && TryParseDouble(parts[1], out var maxVal)) + { + predicates.Add(new FilterPredicate + { + FilterType = FilterType.GreaterThanOrEqual, + PredicateType = PredicateType.And, + FilterMode = filterMode, + FilterValue = minVal + }); + predicates.Add(new FilterPredicate + { + FilterType = FilterType.LessThanOrEqual, + PredicateType = PredicateType.And, + FilterMode = filterMode, + FilterValue = maxVal + }); + return predicates; + } + } + + if ((text.StartsWith(">=") || text.StartsWith(">") || text.StartsWith("<=") || text.StartsWith("<"))) + { + FilterType? type = null; + string numberPart = string.Empty; + + if (text.StartsWith(">=")) + { + type = FilterType.GreaterThanOrEqual; + numberPart = text.Substring(2); + } + else if (text.StartsWith(">")) + { + type = FilterType.GreaterThan; + numberPart = text.Substring(1); + } + else if (text.StartsWith("<=")) + { + type = FilterType.LessThanOrEqual; + numberPart = text.Substring(2); + } + else if (text.StartsWith("<")) + { + type = FilterType.LessThan; + numberPart = text.Substring(1); + } + + if (type.HasValue && TryParseDouble(numberPart, out var value)) + { + predicates.Add(new FilterPredicate + { + FilterType = type.Value, + PredicateType = PredicateType.And, + FilterMode = filterMode, + FilterValue = value + }); + return predicates; + } + } + + predicates.Add(new FilterPredicate + { + FilterType = FilterType.Equals, + PredicateType = PredicateType.And, + FilterMode = filterMode, + FilterValue = text + }); + return predicates; + } + + predicates.Add(new FilterPredicate + { + FilterType = FilterType.Equals, + PredicateType = PredicateType.And, + FilterMode = filterMode, + FilterValue = filterValue + }); + return predicates; + } + + private static bool TryParseDouble(string input, out double value) + { + input = (input ?? string.Empty).Trim(); + return double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out value) || + double.TryParse(input, NumberStyles.Any, CultureInfo.CurrentCulture, out value); + } + + protected override void PopulateComboBoxItems(SfComboBox comboBox, DataGridColumn column) + { + var modifiedItemsSource = new ObservableCollection(); + + foreach (var item in numericComboBoxItems) + { + modifiedItemsSource.Add(item); + } + comboBox.ItemsSource = modifiedItemsSource; + } + + protected override void UpdateDisplayText(SfDataGridFilterRowLabel label, DataGridColumn column) + { + base.UpdateDisplayText(label, column); + + label.Text = selectedText; + } + +} + +{% endhighlight %} +{% endtabs %} + +Customizing Filter Row in MAUI DataGrid + +## Customizing DataGridFilterRowMultiSelectRenderer + +By default, the `SfDataGrid` loads a `ComboBox` when the `FilterRow` enters edit mode. However, you can tailor the `DataGridFilterRowMultiSelectRenderer` to ensure the `ComboBox` is visible immediately upon `FilterRow` initialization. + +{% tabs %} +{% highlight xaml %} + +{% endhighlight %} +{% highlight c# %} + + dataGrid.FilterRowCellRenderers.Remove("MultiSelectComboBox"); + dataGrid.FilterRowCellRenderers.Add("MultiSelectComboBox", new CustomDataGridMultiSelectComboBoxRenderer()); + + public class CustomDataGridMultiSelectComboBoxRenderer : DataGridFilterRowMultiSelectRenderer + { + + public CustomDataGridMultiSelectComboBoxRenderer() + { + SupportsRenderOptimization = false; + IsEditable = true; + } + + + /// + /// Initialize the filter-row display with a live MultiSelect ComboBox instead of a label. + /// + protected override void OnInitializeDisplayView(DataColumnBase dataColumn, SfDataGridContentView? view) + { + InitializeComboBoxView(dataColumn, view); + } + } + +{% endhighlight %} +{% endtabs %} + +Customizing Filter Row in MAUI DataGrid \ No newline at end of file diff --git a/MAUI/DataGrid/Images/columns/maui-datagrid-formatting.png b/MAUI/DataGrid/Images/columns/maui-datagrid-formatting.png new file mode 100644 index 0000000000..bbf2217930 Binary files /dev/null and b/MAUI/DataGrid/Images/columns/maui-datagrid-formatting.png differ diff --git a/MAUI/DataGrid/Images/columns/maui-datagrid-groupName.png b/MAUI/DataGrid/Images/columns/maui-datagrid-groupName.png new file mode 100644 index 0000000000..cc0e66c526 Binary files /dev/null and b/MAUI/DataGrid/Images/columns/maui-datagrid-groupName.png differ diff --git a/MAUI/DataGrid/Images/columns/maui-datagrid-order.png b/MAUI/DataGrid/Images/columns/maui-datagrid-order.png new file mode 100644 index 0000000000..b6d9a03a89 Binary files /dev/null and b/MAUI/DataGrid/Images/columns/maui-datagrid-order.png differ diff --git a/MAUI/DataGrid/Images/conditional-styling/maui-datagrid-customizing-bordercolor_basedon_rowcolumnindex.png b/MAUI/DataGrid/Images/conditional-styling/maui-datagrid-customizing-bordercolor_basedon_rowcolumnindex.png new file mode 100644 index 0000000000..a4fb8dcf34 Binary files /dev/null and b/MAUI/DataGrid/Images/conditional-styling/maui-datagrid-customizing-bordercolor_basedon_rowcolumnindex.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroriconcustomization.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroriconcustomization.png new file mode 100644 index 0000000000..416216ed66 Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroriconcustomization.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroricontemplate.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroricontemplate.png new file mode 100644 index 0000000000..8585d0c9b7 Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroricontemplate.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroricontemplateselector.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroricontemplateselector.png new file mode 100644 index 0000000000..685de56dd9 Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-erroricontemplateselector.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortipcustomization.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortipcustomization.png new file mode 100644 index 0000000000..bf7db1ddfe Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortipcustomization.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortiptemplate.gif b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortiptemplate.gif new file mode 100644 index 0000000000..3fab3c01f3 Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortiptemplate.gif differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortiptemplateselector.gif b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortiptemplateselector.gif new file mode 100644 index 0000000000..b22d2633d6 Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-errortiptemplateselector.gif differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-idataerrorinfo.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-idataerrorinfo.png new file mode 100644 index 0000000000..5e26eec08b Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-idataerrorinfo.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-inotifydataerrorinfo.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-inotifydataerrorinfo.png new file mode 100644 index 0000000000..89f096df96 Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-inotifydataerrorinfo.png differ diff --git a/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-with-masterdetailsview.png b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-with-masterdetailsview.png new file mode 100644 index 0000000000..0ddd2efd8c Binary files /dev/null and b/MAUI/DataGrid/Images/data-validation/maui-datagrid-datavalidation-with-masterdetailsview.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-allowblankfilters.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-allowblankfilters.png new file mode 100644 index 0000000000..5ddfa1c8d5 Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-allowblankfilters.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-basic.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-basic.png new file mode 100644 index 0000000000..0a88f58776 Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-basic.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-cellstyle.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-cellstyle.png new file mode 100644 index 0000000000..f48ebd6b55 Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-cellstyle.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-conditions.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-conditions.png new file mode 100644 index 0000000000..e79d6dc5b9 Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-conditions.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-custommultiselect.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-custommultiselect.png new file mode 100644 index 0000000000..b1291f9dac Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-custommultiselect.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-customnumericrenderer.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-customnumericrenderer.png new file mode 100644 index 0000000000..c61b3cb243 Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-customnumericrenderer.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-multiselectblankfilters.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-multiselectblankfilters.png new file mode 100644 index 0000000000..4966d0a7dd Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-multiselectblankfilters.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-multiselectcombobox.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-multiselectcombobox.png new file mode 100644 index 0000000000..aa67b105ad Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-multiselectcombobox.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-style-filterrowoptionsvisibility.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-style-filterrowoptionsvisibility.png new file mode 100644 index 0000000000..79fe95ed6c Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-style-filterrowoptionsvisibility.png differ diff --git a/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-style.png b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-style.png new file mode 100644 index 0000000000..d1904e28a1 Binary files /dev/null and b/MAUI/DataGrid/Images/filterrow/maui-datagrid-filterrow-style.png differ diff --git a/MAUI/DataGrid/columns.md b/MAUI/DataGrid/columns.md index 0a9a98d0b4..0e66f3ad39 100644 --- a/MAUI/DataGrid/columns.md +++ b/MAUI/DataGrid/columns.md @@ -148,6 +148,152 @@ private void SfDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGenerati {% endhighlight %} {% endtabs %} +### Data Annotations with AutoGenerateColumns + +SfDataGrid support to generate the columns based on built-in [Data Annotation Attributes](https://learn.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/cc490428(v=vs.95)). + +N> Data annotations are only applied when the `DataGrid.AutoGenerateColumns` property is set to True. + +#### Exclude column + +You can skip the column generation using `AutoGenerateField` property. + +{% tabs %} +{% highlight c# %} +[Display(AutoGenerateField = false, Description = "OrderID field is not generated in UI")] +public int OrderID +{ + get { return orderID; } + set { orderID = value; } +} +{% endhighlight %} +{% endtabs %} + +#### Editing + +You can enable editing of cell values by setting the `Editable` attribute to true. + +{% tabs %} +{% highlight c# %} +[Editable(true)] +public string Country +{ + get { return country; } + set { country = value; } +} +{% endhighlight %} +{% endtabs %} + +#### Change the HeaderText of column + +You can customize header text of column using `Display.Name` property or `Display.ShortName` property. + +{% tabs %} +{% highlight c# %} +[Display(Name="Name of the Customer",Description="CustomerName is necessary for identification ")] +public string CustomerName +{ + get { return customerName; } + set { customerName = value; } +} +{% endhighlight %} +{% endtabs %} + +#### Change the order of the columns + +You can change the order of columns using the `Display.Order` property. Columns are arranged based on the specified order value, with lower values appearing first. + +{% tabs %} +{% highlight c# %} +[Display(Order=1)] +public string CustomerID +{ + get { return customerId; } + set { customerId = value; } +} + +[Display(Order=0)] +public int OrderID +{ + get { return orderID; } + set { orderID = value; } +} +{% endhighlight %} +{% endtabs %} + +The OrderID and CustomerID column rearranged based on specified order. + +Changing Columns Order in Maui DataGrid + +#### DataGrid read-only column + +You can disable the editing for a column using `ReadOnly` attribute. + +{% tabs %} +{% highlight c# %} +[ReadOnly(true)] +public string Country +{ + get { return country; } + set { country = value; } +} +{% endhighlight %} +{% endtabs %} + +#### Format datagrid columns using DisplayFormat attribute + +You can format auto-generated columns using the [DisplayFormat](https://learn.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/cc679253%28v%3dvs.95%29) attribute with the [DataFormatString](https://learn.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/cc679306%28v%3dvs.95%29) property defined for properties in the model. + +{% tabs %} +{% highlight c# %} +[DisplayFormat(DataFormatString = "yyyy")] +public DateTime OrderDate +{ + get { return _orderDate; } + set { orderDate = value; } +} + +[DisplayFormat(DataFormatString = "Country is {0}")] +public string Country +{ + get { return country; } + set { country = value; } +} +{% endhighlight %} +{% endtabs %} + +Maui DataGrid with Columns Formatting + +#### Group columns under stacked header +You can group multiple columns under a shared stacked header using the `Display.GroupName` property. Nested grouping is supported using the / separator in the ChildColumns property. + +{% tabs %} +{% highlight c# %} +[Display(GroupName = "Order Details")] +public string? OrderID +{ + get { return orderID; } + set { this.orderID = value; } +} + +[Display(GroupName = "Order Details")] +public DateTime OrderDate +{ + get { return _orderDate; } + set { _orderDate = value; } +} + +[Display(GroupName = "Order Details")] +public string? ShipCountry +{ + get { return shipCountry; } + set { this.shipCountry = value; } +} +{% endhighlight %} +{% endtabs %} + +Maui DataGrid group columns with stacked header + ## Manually generate columns The `SfDataGrid` allows to define the columns manually by adding the [DataGridColumn](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.DataGridColumn.html) objects to the [SfDataGrid.Columns](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html#Syncfusion_Maui_DataGrid_SfDataGrid_Columns) collection. If you want to show only the manually defined columns in the view, you can achieve that by setting the `SfDataGrid.AutoGenerateColumnsMode` property to `None`. @@ -238,3 +384,4 @@ this.dataGrid.Columns.RemoveAt(1); {% endtabs %} + diff --git a/MAUI/DataGrid/conditional-styling.md b/MAUI/DataGrid/conditional-styling.md index 9e9ee14320..fb7edaab20 100644 --- a/MAUI/DataGrid/conditional-styling.md +++ b/MAUI/DataGrid/conditional-styling.md @@ -390,6 +390,60 @@ public class ForeColorConverter : IValueConverter ![Conditional cell styling based on RowIndex and ColumnIndex in .NET MAUI DataGrid](Images/conditional-styling/maui-datagrid-conditional-datagridcelltyle_basedon_rowcolumnindex.png) +### Customizing the BorderColor of a cell +You can customize the border color of individual cells in the SfDataGrid based on RowIndex and ColumnIndex property, and setting the `BorderColor` property in DataGridCell by writing the style for the [DataGridCell](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.DataGridCell.html) + +{% tabs %} +{% highlight xaml tabtitle="MainPage.xaml" %} + + + + + + + + + + + + + + + +{% endhighlight %} +{% highlight xaml tabtitle="BorderColorConverter.cs" %} + +public class BorderColorConverter : IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + var gridCell = value as DataGridCell; + + if (gridCell != null) + { + if (gridCell.DataColumn!.RowIndex == 4 && gridCell.DataColumn.ColumnIndex == 3) + return Colors.Blue; + + return Colors.Transparent; + } + + return Colors.Transparent; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} +{% endhighlight %} +{% endtabs %} + +![Customizing the BorderColor of a cell based on RowIndex and ColumnIndex in .NET MAUI DataGrid](Images/conditional-styling/maui-datagrid-customizing-bordercolor_basedon_rowcolumnindex.png) + ## Style a cell based on cell value Styling can be applied to a particular cell based on CellValue property by writing the style for the [DataGridCell](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.DataGridCell.html) TargetType. diff --git a/MAUI/DataGrid/data-binding.md b/MAUI/DataGrid/data-binding.md index 796a21e441..cf8070872a 100644 --- a/MAUI/DataGrid/data-binding.md +++ b/MAUI/DataGrid/data-binding.md @@ -271,4 +271,82 @@ To retain the scroll position when [ItemsSource](https://help.syncfusion.com/cr/ {% highlight C# %} dataGrid.CanMaintainScrollPosition = true; -{% endhighlight %} \ No newline at end of file +{% endhighlight %} + +## SetCellValue + +The `SetCellValue` method on `SfDataGrid` allows you to programmatically update the value of a specific cell. + +N> +1. For features (like Sorting, Grouping, Filtering) set LiveDataUpdateMode="AllowDataShaping" to ensure the grid updates in live mode after a value change. +2.Caption rows, summary rows, unbound rows and unbound columns cannot be updated by SetCellValue. + +SfDataGrid provides two overloads of SetCellValue: + +1. SetCellValue(int rowIndex, DataGridColumn column, object value) + + + + + + + + + + + + + + + + + + + + + + +
Parameter Type Description
rowIndex int The index of the row in which the cell exists.
column DataGridColumn It represents the column of the cell to be updated.
value object The new value to assign to the cell.
+ +{% tabs %} +{% highlight C# %} + private void Button_Clicked(object sender, EventArgs e) + { + dataGrid.SetCellValue(1, dataGrid.Columns[0], "11111"); + } +{% endhighlight %} +{% endtabs %} + +2. SetCellValue(int rowIndex, string fieldName, object value) + + + + + + + + + + + + + + + + + + + + + + +
Parameter Type Description
rowIndex int The index of the row in which the cell exists.
column string fieldName The name of the property to update in the data record.
value object The new value to assign to the cell.
+ +{% tabs %} +{% highlight C# %} + private void Button_Clicked(object sender, EventArgs e) + { + dataGrid.SetCellValue(1, "OrderID", "11111"); + } +{% endhighlight %} +{% endtabs %} diff --git a/MAUI/DataGrid/data-validation.md b/MAUI/DataGrid/data-validation.md new file mode 100644 index 0000000000..a6d5ea85fe --- /dev/null +++ b/MAUI/DataGrid/data-validation.md @@ -0,0 +1,697 @@ +--- +layout: post +title: Data Validation in .NET MAUI DataGrid control | Syncfusion® +description: Learn all about Data Validation support in Syncfusion® .NET MAUI DataGrid (SfDataGrid) control and more. +platform: MAUI +control: SfDataGrid +documentation: UG +keywords : maui datagrid, maui grid, grid maui, maui gridview, grid in maui, .net maui datagrid, .net maui grid, .net grid maui, .net maui data validation, maui data validation +--- + +# Data Validation in MAUI DataGrid (SfDataGrid) + +[.NET MAUI DataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html) allows you to validate the data and display hints in case of validation is not passed. In case of invalid data, error icon is displayed at the top right corner of DataGridCell. When mouse over the error icon, error information will be displayed in error tip. + +## Built-in Validation + +Built-in validations through `IDataErrorInfo` and `INotifyDataErrorInfo`, can be enabled by setting [SfDataGrid.ValidationMode]() or [DataGridColumn.ValidationMode]() properties. + +`DataGridColumn.ValidationMode` takes priority than `SfDataGrid.ValidationMode`. + +* DataGridValidation.InEdit - display error icon & tips and also doesn’t allow the users to commit the invalid data by not allowing users to edit other cells. +* DataGridValidation.InView - displays error icons and tips alone. +* DataGridValidation.None - disables built-in validation support. + +## Built-in validation using IDataErrorInfo / INotifyDataErrorInfo + +.NET MAUI DataGrid (SfDataGrid) provides support to validate the data based on [IDataErrorInfo](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.idataerrorinfo?view=net-9.0) / [INotifyDataErrorInfo](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=net-9.0). + +### Using IDataErrorInfo + +You can validate the data by inheriting the [IDataErrorInfo](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.idataerrorinfo?view=net-9.0) interface in model class. + +{% tabs %} +{% highlight C# %} + +public class OrderInfo : IDataErrorInfo +{ + private string shipCountry; + + public string ShipCountry + { + get { return shipCountry; } + set { shipCountry = value; } + } + + [Display(AutoGenerateField = false)] + public string Error + { + get + { + return string.Empty; + } + } + + public string this[string columnName] + { + get + { + + if (!columnName.Equals("ShipCountry")) + return string.Empty; + + if (this.ShipCountry == "Canada" || this.ShipCountry == "Belgium") + return "Delivery not available for " + this.ShipCountry; + + return string.Empty; + } + } +} + +{% endhighlight %} +{% endtabs %} + +Enable built-in validation support by setting [SfDataGrid.ValidationMode]() or [DataGridColumn.ValidationMode]() property to `InEdit` or `InView`. + +{% tabs %} +{% highlight XAML %} + + + +{% endhighlight %} +{% highlight C# %} + +this.dataGrid.ValidationMode = DataGridValidationMode.InView; + +{% endhighlight %} +{% endtabs %} + +data-validation-with-IDataErrorInfo + +### Using INotifyDataErrorInfo + +The data can be validated by inheriting the [INotifyDataErrorInfo](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=net-9.0) interface in model class. + +{% tabs %} +{% highlight C# %} + +public class OrderInfo : INotifyDataErrorInfo +{ + private List errors = new List(); + + private string shipCountry; + + public string ShipCountry + { + get { return shipCountry; } + set { shipCountry = value; } + } + + public System.Collections.IEnumerable GetErrors(string propertyName) + { + + if (!propertyName.Equals("ShipCity")) + return null; + + if (this.ShipCity.Contains("Graz") || this.ShipCity.Contains("Montréal")) + errors.Add("Delivery not available for " + this.ShipCity); + return errors; + } + + [Display(AutoGenerateField = false)] + + public bool HasErrors + { + get + { + return false; + } + } + + public event EventHandler ErrorsChanged; +} + +{% endhighlight %} +{% endtabs %} + +Enable built-in validation support by setting [SfDataGrid.ValidationMode]() or [DataGridColumn.ValidationMode]() property to `InEdit` or `InView`. + +{% tabs %} +{% highlight XAML %} + + + +{% endhighlight %} +{% endtabs %} + +data-validation-with-INotifyDataErrorInfo + +## Cell Validation + +A cell can be validated using [CellValidating]() event when the cell is edited. `CellValidating` event occurs when the edited cells tries to commit the data or lose the focus. DataGrid will not allow user to edit other cells if validation failed. + +[DataGridCellValidatingEventArgs]() provides information to `CellValidating` event for validating the cell. `DataGridCellValidatingEventArgs.OriginalSource` returns the DataGrid fired this event for DetailsView. + +`DataGridCellValidatingEventArgs.NewValue` returns the edited value and you can set the validation status using `DataGridCellValidatingEventArgs.IsValid` property. + +{% tabs %} +{% highlight C# %} + +this.dataGrid.CellValidating += dataGrid_CellValidating; + +private void dataGrid_CellValidating(object sender, DataGridCellValidatingEventArgs args) +{ + if (args.NewValue.ToString().Equals("Brazil")) + { + args.IsValid = false; + args.ErrorMessage = "Brazil cannot be passed"; + } +} + +{% endhighlight %} +{% endtabs %} + +[SfDataGrid.CellValidated]() event triggered when the cell has finished validating with valid data. + +{% tabs %} +{% highlight C# %} + +this.dataGrid.CellValidated += dataGrid_CellValidated; + +private void dataGrid_CellValidated(object sender, DataGridCellValidatedEventArgs args) +{ + +} + +{% endhighlight %} +{% endtabs %} + +## Row Validation + +A Row can be validated using [RowValidating]() event when the cell is edited. The `RowValidating` event occurs when the edited cells tries to commit the row data or lose the focus. DataGrid will not allow user to edit other rows if validation failed. + +[DataGridRowValidatingEventArgs]() provides information to `RowValidating` event for validating row. `DataGridRowValidatingEventArgs.OriginalSource` returns the DataGrid fired this event for DetailsView. + +`DataGridRowValidatingEventArgs.RowData` returns the edited value and you can set the validation status using `DataGridRowValidatingEventArgs.IsValid` property. + +{% tabs %} +{% highlight C# %} + +this.dataGrid.RowValidating += dataGrid_RowValidating; + +void dataGrid_RowValidating(object sender, DataGridRowValidatingEventArgs args) +{ + var data = args.RowData.GetType().GetProperty("ShipCountry").GetValue(args.RowData); + + if (data != null && data.ToString().Equals("Austria")) + { + args.IsValid = false; + args.ErrorMessages.Add("ShipCountry", "Austria cannot be passed"); + } +} + +{% endhighlight %} +{% endtabs %} + +[SfDataGrid.RowValidated]() event triggered when the row has finished validating with valid row data. + +{% tabs %} +{% highlight C# %} + +this.dataGrid.RowValidated += dataGrid_RowValidated; + +private void dataGrid_RowValidated(object sender, DataGridRowValidatedEventArgs args) +{ + +} + +{% endhighlight %} +{% endtabs %} + +## Error Icon Customization + +### Change Error Icon Color + +The default error icon color can be customized by setting the [DataGridStyle.ErrorIconColor]() property. + +{% tabs %} +{% highlight XAML %} + + + + + + + +{% endhighlight %} +{% endtabs %} + +data-validation-error-icon-customization + +### Load Error Icon through Template + +The SfDataGrid uses an icon to indicate if a cell has error. You can personalize the error icon by using the [SfDataGrid.ErrorIconTemplate]() property. + +{% tabs %} +{% highlight XAML %} + + + + + + + + + +{% endhighlight %} +{% highlight C# %} +this.dataGrid.ValidationMode = DataGridValidationMode.InView; + +this.dataGrid.ErrorIconTemplate = new DataTemplate(() => +{ + var image = new Image() + { + Source = "error_icon.png", + }; + return image; +}); + +{% endhighlight %} +{% endtabs %} + +data-validation-error-icon-template + +### Load Error Icon through Template Selector + +When choosing a ErrorIconTemplate as a DataTemplateSelector, you have the option to supply distinct templates for different invalid values. + +{% tabs %} +{% highlight XAML %} + + + + + + + + + + + + + + + + + + +{% endhighlight %} +{% highlight C# %} + +public class ErrorIconTemplateSelector: DataTemplateSelector +{ + public DataTemplate BelgiumTemplate { get; set; } + public DataTemplate CanadaTemplate { get; set; } + + protected override DataTemplate OnSelectTemplate(object item, BindableObject container) + { + if (item is Orders order) + { + if (order.ShipCountry == "Belgium") + { + return BelgiumTemplate; + } + else + { + return CanadaTemplate; + } + } + + return CanadaTemplate; + } +} + +{% endhighlight %} +{% endtabs %} + +data-validation-error-icon-template-selector + +## Error Tip Customization + +### Change Error Tip Background and Foreground Color + +The background of the error tip can be changed by setting [DataGridStyle.ErrorTipBackground]() property. The error tip text color can be changed by setting [DataGridStyle.ErrorTipTextColor]() property. + +{% tabs %} +{% highlight XAML %} + + + + + + + +{% endhighlight %} +{% endtabs %} + +data-validation-error-tip-customization + +### Load Error Tip through Template + +The SfDataGrid uses a tool tip to showcase an error message if a cell has error. You can personalize the error tip by using the [SfDataGrid.ErrorTipTemplate]() property. + +{% tabs %} +{% highlight XAML %} + + + + + + + + +{% endhighlight %} +{% highlight C# %} +this.dataGrid.ValidationMode = DataGridValidationMode.InView; + +this.dataGrid.ErrorTipTemplate = new DataTemplate(() => +{ + var label = new Label() + { + Text = "Delivery Not available", + Background = Colors.Orange, + TextColor = Colors.Black + }; + return label; +}); + +{% endhighlight %} +{% endtabs %} + +data-validation-error-tip-template + +### Load Error Tip through Template Selector + +When choosing a ErrorTipTemplate as a DataTemplateSelector, you have the option to supply distinct templates for different invalid values. + +{% tabs %} +{% highlight XAML %} + + + + + + + + + + + + + + + + +{% endhighlight %} +{% highlight C# %} + +public class ErrorTipTemplateSelector: DataTemplateSelector +{ + public DataTemplate BelgiumTemplate { get; set; } + public DataTemplate CanadaTemplate { get; set; } + + protected override DataTemplate OnSelectTemplate(object item, BindableObject container) + { + if (item is Orders order) + { + if (order.ShipCountry == "Belgium") + { + return BelgiumTemplate; + } + else + { + return CanadaTemplate; + } + } + + return CanadaTemplate; + } +} + +{% endhighlight %} +{% endtabs %} + +data-validation-error-tip-template-selector + +## Data Validation with Master-Details View + +The data bound based on [IDataErrorInfo](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.idataerrorinfo?view=net-9.0) or [INotifyDataErrorInfo](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=net-9.0) can be validated by setting [ValidationMode]() property of [DataGridViewDefinition.DataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.DataGridViewDefinition.html). + +{% tabs %} +{% highlight XAML %} + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +When the relation is auto-generated, the data can be validated by setting ValidationMode property to `AutoGeneratingRelations.DataGridViewDefinition.DataGrid` in [AutoGeneratingRelations](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html?tabs=tabid-1#Syncfusion_Maui_DataGrid_SfDataGrid_AutoGeneratingRelations) event handler. + +{% tabs %} +{% highlight C# %} + +dataGrid.AutoGenerateRelations = true; + +dataGrid.AutoGeneratingRelations += dataGrid_AutoGeneratingRelations; + +void dataGrid_AutoGeneratingRelations(object sender, AutoGeneratingRelationsArgs e) +{ + e.DataGridViewDefinition.DataGrid.ValidationMode = DataGridValidationMode.InView; +} + +{% endhighlight %} +{% endtabs %} + +data-validation-with-master-details-view + +### Custom validation through events + +Master-Details View support to validate the cells and rows using [CellValidating]() and [RowValidating]() events. + +#### Cell Validation + +The cells can be validated using [CellValidating]() event of [ViewDefinition.DataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.ViewDefinition.html) when the cell is edited. `CellValidating` event occurs when the edited cells tries to commit the data or lose the focus. + +{% tabs %} +{% highlight XAML %} + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +{% tabs %} +{% highlight C# %} + +this.FirstLevelNestedGrid.CellValidating += FirstLevelNestedGrid_CellValidating; + +private void FirstLevelNestedGrid_CellValidating(object sender, DataGridCellValidatingEventArgs args) +{ + + if (args.NewValue.ToString().Equals("SIMOB")) + { + args.IsValid = false; + args.ErrorMessage = "SIMOB cannot be passed"; + } +} + +{% endhighlight %} +{% endtabs %} + +[CellValidated]() event [ViewDefinition.DataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.ViewDefinition.html) triggered when the cell has finished validating with valid data. + +{% tabs %} +{% highlight C# %} + +this.FirstLevelNestedGrid.CellValidated += FirstLevelNestedGrid_CellValidated; + +private void FirstLevelNestedGrid_CellValidated(object sender, DataGridCellValidatedEventArgs args) +{ + +} + +{% endhighlight %} +{% endtabs %} + +When the relation is auto-generated, you can wire the `CellValidating` and `CellValidated` events for `AutoGeneratingRelations.DataGridViewDefinition.DataGrid` in [AutoGeneratingRelations](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html?tabs=tabid-1#Syncfusion_Maui_DataGrid_SfDataGrid_AutoGeneratingRelations) event handler. + +{% tabs %} +{% highlight C# %} + +dataGrid.AutoGenerateRelations = true; +dataGrid.AutoGeneratingRelations += dataGrid_AutoGeneratingRelations; + +private void dataGrid_AutoGeneratingRelations(object sender, AutoGeneratingRelationsArgs e) +{ + e.DataGridViewDefinition.DataGrid.CellValidating += FirstLevelNestedGrid_CurrentCellValidating; + e.DataGridViewDefinition.DataGrid.CellValidated += FirstLevelNestedGrid_CurrentCellValidated; +} + +{% endhighlight %} +{% endtabs %} + +#### Row Validation + +The row can be validated using [RowValidating]() event of [ViewDefinition.DataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.ViewDefinition.html) when the cell is edited. + +The `RowValidating` event occurs when edited cells tries to commit the row data or lose the focus. + +{% tabs %} +{% highlight XAML %} + + + + + + + + + + + +{% endhighlight %} +{% endtabs %} + +{% tabs %} +{% highlight C# %} + +this.FirstLevelNestedGrid.RowValidating += FirstLevelNestedGrid_RowValidating; + +private void FirstLevelNestedGrid_RowValidating(object sender, DataGridRowValidatingEventArgs args) +{ + var data = args.RowData.GetType().GetProperty("CustomerID").GetValue(args.RowData); + + if (data.ToString().Equals("MEREP")) + { + args.IsValid = false; + args.ErrorMessages.Add("CustomerID", "MEREP cannot be passed"); + } +} + +{% endhighlight %} +{% endtabs %} + +[RowValidated]() of [ViewDefinition.DataGrid](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.ViewDefinition.html) event triggered when the row has finished validating with valid row data. + +{% tabs %} +{% highlight C# %} + +this.FirstLevelNestedGrid.RowValidated += FirstLevelNestedGrid_RowValidated; + +private void FirstLevelNestedGrid_RowValidated(object sender, DataGridRowValidatedEventArgs args) +{ + +} + +{% endhighlight %} +{% endtabs %} + +When the relation is auto-generated, you can wire the `RowValidating` and `RowValidated` events for `AutoGeneratingRelations.DataGridViewDefinition.DataGrid` in [AutoGeneratingRelations](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.DataGrid.SfDataGrid.html?tabs=tabid-1#Syncfusion_Maui_DataGrid_SfDataGrid_AutoGeneratingRelations) event handler. + +{% tabs %} +{% highlight C# %} + +dataGrid.AutoGenerateRelations = true; +dataGrid.AutoGeneratingRelations += dataGrid_AutoGeneratingRelations; + +private void dataGrid_AutoGeneratingRelations(object sender, AutoGeneratingRelationsArgs e) +{ + e.DataGridViewDefinition.DataGrid.RowValidating += FirstLevelNestedGrid_RowValidating; + e.DataGridViewDefinition.DataGrid.RowValidated += FirstLevelNestedGrid_RowValidated; +} + +{% endhighlight %} +{% endtabs %} + +## Limitations + +N> +1. Non editable columns will not support custom validation. diff --git a/MAUI/DataGrid/localization.md b/MAUI/DataGrid/localization.md index fa6abc502a..aac3d95ca2 100644 --- a/MAUI/DataGrid/localization.md +++ b/MAUI/DataGrid/localization.md @@ -12,6 +12,31 @@ documentation: ug Localization is the process of translating the application resources into different language for the specific cultures. The `SfDataGrid` can be localized by adding `resource` file. In `SfDataGrid`, provides the support to localize the below strings * `Load More` + * `Click here to add new row` + * `Equals` + * `Does Not Equal` + * `Greater Than` + * `Greater Than or Equal` + * `Less Than` + * `Less Than or Equal` + * `Begins With` + * `Does Not Begin With` + * `Ends With` + * `Does Not End With` + * `Contains` + * `Does Not Contain` + * `Before` + * `Before or Equal` + * `After` + * `After or Equal` + * `Empty` + * `Not Empty` + * `Null` + * `Not Null` + * `(Blanks)` + * `(Select All)` + * `Ok` + * `Cancel` ## Setting CurrentUICulture to the application diff --git a/MAUI/DateTimePicker/images/intervals/maui-date-time-picker-millisecond-interval.png b/MAUI/DateTimePicker/images/intervals/maui-date-time-picker-millisecond-interval.png index fa54f6fc4c..d150baeb2f 100644 Binary files a/MAUI/DateTimePicker/images/intervals/maui-date-time-picker-millisecond-interval.png and b/MAUI/DateTimePicker/images/intervals/maui-date-time-picker-millisecond-interval.png differ diff --git a/MAUI/ImageEditor/events.md b/MAUI/ImageEditor/events.md index 5b67d06ed9..f4f7c96814 100644 --- a/MAUI/ImageEditor/events.md +++ b/MAUI/ImageEditor/events.md @@ -19,16 +19,17 @@ This [`ImageLoaded`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.ImageEd {% highlight xaml tabtitle="MainPage.xaml" %} - + {% endhighlight %} {% highlight C# tabtitle="MainPage.xaml.cs" %} - private void OnImageLoaded(object sender, EventArgs e) - { - this.imageEditor.Rotate(); - } +private void OnImageLoaded(object sender, EventArgs e) +{ + this.imageEditor.Rotate(); +} {% endhighlight %} @@ -38,23 +39,23 @@ N> [View sample in GitHub](https://github.com/SyncfusionExamples/maui-image-edit ## Annotations deserialized event -This `AnnotationsDeserialized` event occurs when annotations are deserialized onto the image. +This [AnnotationsDeserialized](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.ImageEditor.SfImageEditor.html#Syncfusion_Maui_ImageEditor_SfImageEditor_AnnotationsDeserialized) event occurs when the annotations are deserialized onto the image. N> `Serialization` and `deserialization` are not applicable for custom annotation views. {% tabs %} {% highlight xaml tabtitle="MainPage.xaml" hl_lines="3" %} - + {% endhighlight %} {% highlight C# tabtitle="MainPage.xaml.cs" %} - private async void OnAnnotationsDeserialized(object? sender, EventArgs e) - { - await DisplayAlert("", "Annotations are deserialized", "Ok"); - } +private async void OnAnnotationsDeserialized(object? sender, EventArgs e) +{ + await DisplayAlert("", "Annotations are deserialized", "Ok"); +} {% endhighlight %} {% endtabs %} @@ -69,19 +70,20 @@ N> This is common for Shape and Text annotations. {% highlight xaml tabtitle="MainPage.xaml" %} - + {% endhighlight %} {% highlight C# tabtitle="MainPage.xaml.cs" %} - private void OnAnnotationSelected(object sender, AnnotationSelectedEventArgs e) +private void OnAnnotationSelected(object sender, AnnotationSelectedEventArgs e) +{ + if (e.AnnotationSettings is ImageEditorShapeSettings shapeSettings) { - if (e.AnnotationSettings is ImageEditorShapeSettings shapeSettings) - { - shapeSettings.Color = Colors.Black; - } + shapeSettings.Color = Colors.Black; } +} {% endhighlight %} @@ -96,16 +98,17 @@ The [`BrowseImage`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.ImageEdi {% highlight xaml tabtitle="MainPage.xaml" %} - + {% endhighlight %} {% highlight C# tabtitle="MainPage.xaml.cs" %} - private void OnImageBrowse(object sender, CancelEventArgs e) - { - e.Cancel = true; - } +private void OnImageBrowse(object sender, CancelEventArgs e) +{ + e.Cancel = true; +} {% endhighlight %} diff --git a/MAUI/Kanban-Board/Sorting.md b/MAUI/Kanban-Board/Sorting.md new file mode 100644 index 0000000000..db278c161b --- /dev/null +++ b/MAUI/Kanban-Board/Sorting.md @@ -0,0 +1,484 @@ +--- +layout: post +title: Sorting in .NET MAUI Kanban control | Syncfusion® +description: Learn here all about Sorting support in Syncfusion® .NET MAUI Kanban Board (SfKanban) control and more. +platform: maui +control: Kanban (SfKanban) +documentation: ug +keywords: .net maui Kanban sorting, sfKanban sorting in .net maui, .net maui Kanban sorting support. +--- + +# Card Item Sorting in .NET MAUI Kanban (SfKanban) + +The Kanban control supports customizable card sorting within columns based on specific data fields such as `Priority`, `DueDate`, or `Status`. Sorting can be configured programmatically and updated dynamically at runtime using the following properties: + +* [SortingMappingPath](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingMappingPath) - Used to map the sorting field to a property name in the [KanbanModel](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.KanbanModel.html) or `CustomModel`. The default value is `string.Empty`, in which case the cards will not be sorted. +* [SortingOrder](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingOrder) - Used to define the direction of cards sorting within each column. + * [Ascending](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.KanbanSortingOrder.html#Syncfusion_Maui_Kanban_KanbanSortingOrder_Ascending) - Cards with lower values appear first. + * [Descending](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.KanbanSortingOrder.html#Syncfusion_Maui_Kanban_KanbanSortingOrder_Descending) - Cards with higher values appear first. + +N> The [SortingOrder](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingOrder) property is applicable only when a valid value is assigned to [SortingMappingPath](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingMappingPath). + +## Customize card order with sorting configuration + +Sorting in the Kanban control can be implemented using the following approaches. + + * Custom + * Index + +### Custom Field Sorting + +To enable custom sorting behavior, a valid property name from the [ItemsSource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_ItemsSource) must be mapped using the [SortingMappingPath](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingMappingPath) property. This mapping ensures that cards are loaded and repositioned based on the corresponding property value, allowing consistent sorting during both initialization and drag-and-drop operations. + +This example demonstrates how card positions are updated based on sorting configurations and property mappings. + +{% tabs %} +{% highlight XAML hl_lines="2 3 5" %} + + + + + + + + + + + + + + + + + + + + +{% endhighlight %} +{% highlight C# hl_lines="2 6" %} + +this.kanban.ItemsSource = new SortingViewModel().Cards; +this.kanban.DragEnd += this.OnCardDragEnd; + +private void OnCardDragEnd(object? sender, KanbanDragEndEventArgs e) +{ + this.kanban.RefreshKanbanColumn(); +} + +{% endhighlight %} +{% highlight c# tabtitle="CardDetails.cs" %} + +public class CardDetails +{ + public string? Title { get; set; } + public string? Description { get; set; } + public string? Priority { get; set; } + public string? Category { get; set; } +} + +{% endhighlight %} +{% highlight c# tabtitle="SortingViewModel.cs" %} + +public class SortingViewModel +{ + public SortingViewModel() + { + this.Cards = new ObservableCollection() + { + new CardDetails() { Title = "Task - 1", Priority = "Medium", Category = "Open", Description = "Fix the issue reported in the Edge browser." }, + new CardDetails() { Title = "Task - 3", Priority = "Low", Category = "In Progress", Description = "Analyze the new requirements gathered from the customer." }, + new CardDetails() { Title = "Task - 4", Priority = "Critical", Category = "Open", Description = "Arrange a web meeting with the customer to get new requirements." }, + new CardDetails() { Title = "Task - 2", Priority = "High", Category = "In Progress", Description = "Test the application in the Edge browser." }, + new CardDetails() { Title = "Task - 5", Priority = "Medium", Category = "Done", Description = "Enhance editing functionality." }, + new CardDetails() { Title = "Task - 8", Priority = "Medium", Category = "In Progress", Description = "Improve application performance." }, + new CardDetails() { Title = "Task - 9", Priority = "Medium", Category = "Done", Description = "Improve the performance of the editing functionality." }, + new CardDetails() { Title = "Task - 10", Priority = "High", Category = "Open", Description = "Analyze grid control." }, + new CardDetails() { Title = "Task - 12", Priority = "Low", Category = "Done", Description = "Analyze stored procedures." } + }; + } + + public ObservableCollection Cards { get; set; } +} + +{% endhighlight %} +{% endtabs %} + +![custom-field-sorting-in-maui-kanban](images/sorting/custom-field-sorting-in-maui-kanban.gif) + +N> +[View sample in GitHub](https://github.com/SyncfusionExamples/maui-kanban-examples/tree/master/CustomFieldSorting) + +N> + * To apply sorting after a drop operation, handle the [DragEnd](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_DragEnd) event and explicitly call the [RefreshKanbanColumn](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_RefreshKanbanColumn) method. This ensures the column updates to reflect the new card order based on the defined sorting logic. + * When using a custom data model, the default card UI is not applicable. To render the card content, you must define a custom `DataTemplate` using the [CardTemplate](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_CardTemplate) property. + +### Index-Based Sorting + +The index-based approach in the Kanban control allows cards to be dropped at precise positions within a column. Upon dropping, the card's index is updated based on the index of the previous card. Additionally, the index of the next card is incremented relative to the drop position to maintain continuous ordering. + +N> The [SortingMappingPath](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingMappingPath) property must be mapped to a valid numeric property name from the [ItemsSource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_ItemsSource) to enable index-based sorting updates. + +The following code example illustrates how cards numeric property updated using the index-based sorting approach. + +{% tabs %} +{% highlight XAML hl_lines="2 3 5" %} + + + + + + + + + + + + + + + + + + + + +{% endhighlight %} +{% highlight C# hl_lines="1 2 11 12" %} + +this.kanban.ItemsSource = new SortingViewModel().Cards; +this.kanban.DragEnd += this.OnCardDragEnd; + +private void OnCardDragEnd(object? sender, KanbanDragEndEventArgs e) +{ + if (this.kanban == null) + { + return; + } + + this.ApplySortingWithoutPositionChange(e); + this.kanban.RefreshKanbanColumn(); +} + +private void ApplySortingWithoutPositionChange(KanbanDragEndEventArgs eventArgs) +{ + if (this.kanban == null || eventArgs.Data == null || eventArgs.TargetColumn?.Items == null || eventArgs.SourceColumn == null || (eventArgs.SourceColumn == eventArgs.TargetColumn && eventArgs.SourceIndex == eventArgs.TargetIndex)) + { + return; + } + + // Retrieve sorting configuration + var sortMappingPath = kanban.SortingMappingPath; + var sortingOrder = kanban.SortingOrder; + + // Extract and cast items from the target column + var targetColumnItems = eventArgs.TargetColumn.Items is IList items + ? items.Cast().ToList() : new List(); + + // Proceed only if sorting path is defined + if (string.IsNullOrEmpty(sortMappingPath)) + { + return; + } + + // Sort items based on the sorting order + if (targetColumnItems.Count > 0) + { + Func keySelector = item => this.GetPropertyInfo(item.GetType(), sortMappingPath); + + targetColumnItems = sortingOrder == KanbanSortingOrder.Ascending + ? targetColumnItems.OrderBy(item => keySelector(item) ?? 0).ToList() + : targetColumnItems.OrderByDescending(item => keySelector(item) ?? 0).ToList(); + } + + // Determine the index to insert the dragged card. + int currentCardIndex = eventArgs.TargetIndex; + if (currentCardIndex >= 0 && currentCardIndex <= targetColumnItems.Count) + { + targetColumnItems.Insert(currentCardIndex, eventArgs.Data); + } + else + { + targetColumnItems.Add(eventArgs.Data); + currentCardIndex = targetColumnItems.Count - 1; + } + + // Update index property of all items using smart positioning logic + this.ApplySmartIndexUpdate(targetColumnItems, sortingOrder, currentCardIndex); +} + +private void ApplySmartIndexUpdate(List items, KanbanSortingOrder sortingOrder, int currentCardIndex) +{ + if (items == null || items.Count == 0) + { + return; + } + + if (sortingOrder == KanbanSortingOrder.Ascending) + { + this.HandleAscendingIndexSorting(items, currentCardIndex); + return; + } + + this.HandleDescendingIndexSorting(items, currentCardIndex); +} + +private void HandleAscendingIndexSorting(List items, int currentCardIndex) +{ + int afterCardIndex = -1; + int lastItemIndex = -1; + + // Get the index of the card after the insertion point + if (currentCardIndex < items.Count - 1) + { + var afterCard = items[currentCardIndex + 1]; + afterCardIndex = GetCardIndex(afterCard) ?? -1; + } + + for (int i = 0; i < items.Count; i++) + { + var item = items[i]; + if (item == null) + { + continue; + } + + PropertyInfo? propertyInfo = this.GetPropertyInfo(item.GetType(), "Index"); + if (propertyInfo == null) + { + continue; + } + + int itemIndex = Convert.ToInt32(propertyInfo.GetValue(item) ?? 0); + bool isFirstItem = i == 0; + if (isFirstItem) + { + // If the inserted card is at the beginning, assign a smart index + if (currentCardIndex == 0) + { + lastItemIndex = afterCardIndex > 1 ? afterCardIndex - 1 : 1; + propertyInfo.SetValue(item, lastItemIndex); + } + else + { + lastItemIndex = itemIndex; + } + } + else + { + // Increment index for subsequent items + lastItemIndex++; + propertyInfo.SetValue(item, lastItemIndex); + } + } +} + +private void HandleDescendingIndexSorting(List items, int currentCardIndex) +{ + int beforeCardIndex = -1; + int lastItemIndex = -1; + + // Get the index of the card before the insertion point + if (currentCardIndex > 0 && currentCardIndex < items.Count) + { + var cardBefore = items[currentCardIndex - 1]; + beforeCardIndex = GetCardIndex(cardBefore) ?? -1; + } + + for (int i = items.Count - 1; i >= 0; i--) + { + var item = items[i]; + if (item == null) + { + continue; + } + + PropertyInfo? propertyInfo = this.GetPropertyInfo(item.GetType(), "Index"); + if (propertyInfo == null) + { + continue; + } + + int itemIndex = Convert.ToInt32(propertyInfo.GetValue(item) ?? 0); + bool isLastItem = i == items.Count - 1; + if (isLastItem) + { + // If the inserted card is at the end, assign a smart index + if (currentCardIndex == items.Count - 1) + { + lastItemIndex = beforeCardIndex > 1 ? beforeCardIndex - 1 : 1; + propertyInfo.SetValue(item, lastItemIndex); + } + else + { + lastItemIndex = itemIndex; + } + } + else + { + lastItemIndex++; + propertyInfo.SetValue(item, lastItemIndex); + } + } +} + +private int? GetCardIndex(object cardDetails) +{ + if (cardDetails == null) + { + return null; + } + + PropertyInfo? propertyInfo = this.GetPropertyInfo(cardDetails.GetType(), "Index"); + if (propertyInfo == null) + { + return null; + } + + var indexValue = propertyInfo.GetValue(cardDetails); + if (indexValue != null) + { + return Convert.ToInt32(indexValue); + } + + return null; +} + +private PropertyInfo? GetPropertyInfo(Type type, string key) +{ + return this.GetPropertyInfoCustomType(type, key); +} + +private PropertyInfo? GetPropertyInfoCustomType([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] Type type, string key) +{ + return type.GetProperty(key); +} + +{% endhighlight %} +{% highlight c# tabtitle="CardDetails.cs" %} + +public class CardDetails +{ + public string? Title { get; set; } + public string? Description { get; set; } + public int? Index { get; set; } + public string? Category { get; set; } +} + +{% endhighlight %} +{% highlight c# tabtitle="SortingViewModel.cs" %} + +public class SortingViewModel +{ + public SortingViewModel() + { + this.Cards = new ObservableCollection() + { + new CardDetails() { Title = "Task - 1", Index = 5, Category = "Open", Description = "Fix the issue reported in the Edge browser." }, + new CardDetails() { Title = "Task - 3", Index = 9, Category = "In Progress", Description = "Analyze the new requirements gathered from the customer." }, + new CardDetails() { Title = "Task - 4", Index = 2, Category = "Open", Description = "Arrange a web meeting with the customer to get new requirements." }, + new CardDetails() { Title = "Task - 2", Index = 1, Category = "In Progress", Description = "Test the application in the Edge browser." }, + new CardDetails() { Title = "Task - 5", Index = 8, Category = "Done", Description = "Enhance editing functionality." }, + new CardDetails() { Title = "Task - 8", Index = 3, Category = "In Progress", Description = "Improve application performance." }, + new CardDetails() { Title = "Task - 9", Index = 6, Category = "Done", Description = "Improve the performance of the editing functionality." }, + new CardDetails() { Title = "Task - 10", Index = 4, Category = "Open", Description = "Analyze grid control." }, + new CardDetails() { Title = "Task - 12", Index = 7, Category = "Done", Description = "Analyze stored procedures." } + }; + } + + public ObservableCollection Cards { get; set; } +} + +{% endhighlight %} +{% endtabs %} + +![index-based-sorting-in-maui-kanban](images/sorting/index-based-sorting-in-maui-kanban.gif) + +N> +[View sample in GitHub](https://github.com/SyncfusionExamples/maui-kanban-examples/tree/master/IndexBasedSorting) + +N> + * The Index-based sorting can be achieved at the sample level after a drag-and-drop action. To implement this handle the [DragEnd](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_DragEnd) event, access the items in the target column using [e.TargetColumn.Items](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.KanbanColumn.html#Syncfusion_Maui_Kanban_KanbanColumn_Items), and update the numeric field used for sorting to maintain a continuous order. Finally, call [RefreshKanbanColumn](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_RefreshKanbanColumn) method to update the UI with the new order. + * To disable sorting logic, avoid assigning a value to the [SortingMappingPath](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_SortingMappingPath) property. This ensures that card positions remain static and reflect the order of the [ItemsSource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Kanban.SfKanban.html#Syncfusion_Maui_Kanban_SfKanban_ItemsSource) collection, making it suitable for scenarios where sorting is not required or is managed externally. diff --git a/MAUI/Kanban-Board/images/sorting/custom-field-sorting-in-maui-kanban.gif b/MAUI/Kanban-Board/images/sorting/custom-field-sorting-in-maui-kanban.gif new file mode 100644 index 0000000000..4c5ef2bdcd Binary files /dev/null and b/MAUI/Kanban-Board/images/sorting/custom-field-sorting-in-maui-kanban.gif differ diff --git a/MAUI/Kanban-Board/images/sorting/index-based-sorting-in-maui-kanban.gif b/MAUI/Kanban-Board/images/sorting/index-based-sorting-in-maui-kanban.gif new file mode 100644 index 0000000000..92fc43afa6 Binary files /dev/null and b/MAUI/Kanban-Board/images/sorting/index-based-sorting-in-maui-kanban.gif differ diff --git a/MAUI/Release-notes/v31.2.2.md b/MAUI/Release-notes/v31.2.2.md index 9b976198ea..6e845deef3 100644 --- a/MAUI/Release-notes/v31.2.2.md +++ b/MAUI/Release-notes/v31.2.2.md @@ -7,7 +7,7 @@ documentation: ug # Essential Studio® for MAUI - v31.2.2 Release Notes -{% include release-info.html date="October 14, 2025" version="v31.2.2" passed="43242" failed="0" %} +{% include release-info.html date="October 15, 2025" version="v31.2.2" passed="43242" failed="0" %} {% directory path: _includes/release-notes/v31.2.2 %} diff --git a/MAUI/Release-notes/v31.2.3.md b/MAUI/Release-notes/v31.2.3.md new file mode 100644 index 0000000000..2ee11d93cf --- /dev/null +++ b/MAUI/Release-notes/v31.2.3.md @@ -0,0 +1,72 @@ +--- +title: Essential Studio® for MAUI Release Notes - v31.2.3 +description: Learn here about the controls in the Essential Studio® for MAUI Weekly Nuget Release - Release Notes - v31.2.3 +platform: maui +documentation: ug +--- + +# Essential Studio® for MAUI - v31.2.3 Release Notes + +{% include release-info.html date="October 22, 2025" version="v31.2.3" passed="43242" failed="0" %} + +{% directory path: _includes/release-notes/v31.2.3 %} + +{% include {{file.url}} %} + +{% enddirectory %} + +## Test Results + +| Component Name | Test Cases | Passed | Failed | Remarks | +|---------------|------------|--------|--------|---------| +| SfAccordion | 63 | 63 | 0 | All Passed | +| SfAIAssistView | 145 | 145 | 0 | All Passed | +| SfAutocomplete | 262 | 262 | 0 | All Passed | +| SfAvatarView | 56 | 56 | 0 | All Passed | +| SfBackDropPage | 83 | 83 | 0 | All Passed | +| SfBadgeView | 81 | 81 | 0 | All Passed | +| SfBarcodeGenerator | 1763 | 1763 | 0 | All Passed | +| SfBusyIndicator | 91 | 91 | 0 | All Passed | +| SfButton | 104 | 104 | 0 | All Passed | +| SfCalendar | 2345 | 2345 | 0 | All Passed | +| SfCards | 235 | 235 | 0 | All Passed | +| SfCarousel | 203 | 203 | 0 | All Passed | +| SfCharts | 521 | 521 | 0 | All Passed | +| SfChat | 59 | 59 | 0 | All Passed | +| SfCheck Box | 154 | 154 | 0 | All Passed | +| SfChip | 73 | 73 | 0 | All Passed | +| SfComboBox | 344 | 344 | 0 | All Passed | +| SfDataForms | 3324 | 3324 | 0 | All Passed | +| SfDataGrid | 2464 | 2464 | 0 | All Passed | +| SfEffectsView | 61 | 61 | 0 | All Passed | +| SfExpander | 215 | 215 | 0 | All Passed | +| SfGauge | 1184 | 1184 | 0 | All Passed | +| SfImageEditor | 3393 | 3393 | 0 | All Passed | +| SfKanban | 204 | 204 | 0 | All Passed | +| SfListView | 4638 | 4638 | 0 | All Passed | +| SfMaps | 1229 | 1229 | 0 | All Passed | +| SfMarkdownViewer | 69 | 69 | 0 | All Passed | +| SfMaskedEntry | 174 | 174 | 0 | All Passed | +| SfNavigationDrawer | 125 | 125 | 0 | All Passed | +| SfNumericEntry | 233 | 233 | 0 | All Passed | +| SfNumericUpDown | 233 | 233 | 0 | All Passed | +| SfOTPInput | 55 | 55 | 0 | All Passed | +| SfPicker | 457 | 457 | 0 | All Passed | +| SfPopup | 1240 | 1240 | 0 | All Passed | +| SfProgressBar | 624 | 624 | 0 | All Passed | +| SfRadialMenu | 200 | 200 | 0 | All Passed | +| SfRadioButton | 183 | 183 | 0 | All Passed | +| SfRating | 200 | 200 | 0 | All Passed | +| SfRichTextEditor | 157 | 157 | 0 | All Passed | +| SfRotator | 1194 | 1194 | 0 | All Passed | +| SfScheduler | 10977 | 10977 | 0 | All Passed | +| SfSegment | 338 | 338 | 0 | All Passed | +| SfShimmer | 371 | 371 | 0 | All Passed | +| SfSignaturePad | 32 | 32 | 0 | All Passed | +| SfSlider | 292 | 292 | 0 | All Passed | +| SfSwitch | 131 | 131 | 0 | All Passed | +| SfTab View | 1620 | 1620 | 0 | All Passed | +| SfTextInputLayout | 199 | 199 | 0 | All Passed | +| SfToolBar | 139 | 139 | 0 | All Passed | +| SfTreeMap | 454 | 454 | 0 | All Passed | +| SfTreeView | 251 | 251 | 0 | All Passed | \ No newline at end of file diff --git a/MAUI/Release-notes/v31.2.4.md b/MAUI/Release-notes/v31.2.4.md new file mode 100644 index 0000000000..bf40ada97d --- /dev/null +++ b/MAUI/Release-notes/v31.2.4.md @@ -0,0 +1,71 @@ +--- +title: Essential Studio® for MAUI Release Notes - v31.2.4 +description: Learn here about the controls in the Essential Studio® for MAUI Weekly Nuget Release - Release Notes - v31.2.4 +platform: maui +documentation: ug +--- + +# Essential Studio® for MAUI - v31.2.4 Release Notes + +{% include release-info.html date="October 28, 2025" version="v31.2.4" passed="40897" failed="0" %} + +{% directory path: _includes/release-notes/v31.2.4 %} + +{% include {{file.url}} %} + +{% enddirectory %} + +## Test Results + +| Component Name | Test Cases | Passed | Failed | Remarks | +|---------------|------------|--------|--------|---------| +| SfAccordion | 63 | 63 | 0 | All Passed | +| SfAIAssistView | 145 | 145 | 0 | All Passed | +| SfAutocomplete | 262 | 262 | 0 | All Passed | +| SfAvatarView | 56 | 56 | 0 | All Passed | +| SfBackDropPage | 83 | 83 | 0 | All Passed | +| SfBadgeView | 81 | 81 | 0 | All Passed | +| SfBarcodeGenerator | 1763 | 1763 | 0 | All Passed | +| SfBusyIndicator | 91 | 91 | 0 | All Passed | +| SfButton | 104 | 104 | 0 | All Passed | +| SfCards | 235 | 235 | 0 | All Passed | +| SfCarousel | 203 | 203 | 0 | All Passed | +| SfCharts | 521 | 521 | 0 | All Passed | +| SfChat | 59 | 59 | 0 | All Passed | +| SfCheck Box | 154 | 154 | 0 | All Passed | +| SfChip | 73 | 73 | 0 | All Passed | +| SfComboBox | 344 | 344 | 0 | All Passed | +| SfDataForms | 3324 | 3324 | 0 | All Passed | +| SfDataGrid | 2464 | 2464 | 0 | All Passed | +| SfEffectsView | 61 | 61 | 0 | All Passed | +| SfExpander | 215 | 215 | 0 | All Passed | +| SfGauge | 1184 | 1184 | 0 | All Passed | +| SfImageEditor | 3393 | 3393 | 0 | All Passed | +| SfKanban | 204 | 204 | 0 | All Passed | +| SfListView | 4638 | 4638 | 0 | All Passed | +| SfMaps | 1229 | 1229 | 0 | All Passed | +| SfMarkdownViewer | 69 | 69 | 0 | All Passed | +| SfMaskedEntry | 174 | 174 | 0 | All Passed | +| SfNavigationDrawer | 125 | 125 | 0 | All Passed | +| SfNumericEntry | 233 | 233 | 0 | All Passed | +| SfNumericUpDown | 233 | 233 | 0 | All Passed | +| SfOTPInput | 55 | 55 | 0 | All Passed | +| SfPicker | 457 | 457 | 0 | All Passed | +| SfPopup | 1240 | 1240 | 0 | All Passed | +| SfProgressBar | 624 | 624 | 0 | All Passed | +| SfRadialMenu | 200 | 200 | 0 | All Passed | +| SfRadioButton | 183 | 183 | 0 | All Passed | +| SfRating | 200 | 200 | 0 | All Passed | +| SfRichTextEditor | 157 | 157 | 0 | All Passed | +| SfRotator | 1194 | 1194 | 0 | All Passed | +| SfScheduler | 10977 | 10977 | 0 | All Passed | +| SfSegment | 338 | 338 | 0 | All Passed | +| SfShimmer | 371 | 371 | 0 | All Passed | +| SfSignaturePad | 32 | 32 | 0 | All Passed | +| SfSlider | 292 | 292 | 0 | All Passed | +| SfSwitch | 131 | 131 | 0 | All Passed | +| SfTab View | 1620 | 1620 | 0 | All Passed | +| SfTextInputLayout | 199 | 199 | 0 | All Passed | +| SfToolBar | 139 | 139 | 0 | All Passed | +| SfTreeMap | 454 | 454 | 0 | All Passed | +| SfTreeView | 251 | 251 | 0 | All Passed | \ No newline at end of file diff --git a/MAUI/Rich-Text-Editor/Customization.md b/MAUI/Rich-Text-Editor/Customization.md index 7deddec0c9..c73eefc6f5 100644 --- a/MAUI/Rich-Text-Editor/Customization.md +++ b/MAUI/Rich-Text-Editor/Customization.md @@ -21,7 +21,7 @@ By default, the toolbar includes a comprehensive set of formatting tools. You ca The following items are available to be added to the `ToolbarItems` collection: * `Bold`, `Italic`, `Underline`, `Strikethrough` -* `Subscript`, `Superscript` +* `SubScript`, `SuperScript` * `FontFamily`, `FontSize`, `TextColor`, `HighlightColor` * `ParagraphFormat` , `Alignment` * `NumberList`, `BulletList` diff --git a/MAUI/Scheduler/drag-and-drop-appointments.md b/MAUI/Scheduler/drag-and-drop-appointments.md index 1568b82bc7..16404fe64e 100644 --- a/MAUI/Scheduler/drag-and-drop-appointments.md +++ b/MAUI/Scheduler/drag-and-drop-appointments.md @@ -98,7 +98,7 @@ Using the [AppointmentDrop](https://help.syncfusion.com/cr/maui/Syncfusion.Maui. [DropTime](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.AppointmentDropEventArgs.html#Syncfusion_Maui_Scheduler_AppointmentDropEventArgs_DropTime) - Get or set the date and time at which the appointment is being dropped. [SourceResource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.AppointmentDropEventArgs.html#Syncfusion_Maui_Scheduler_AppointmentDropEventArgs_SourceResource) - Get the original resource of the appointment that is being dropped. [TargetResource](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.AppointmentDropEventArgs.html#Syncfusion_Maui_Scheduler_AppointmentDropEventArgs_TargetResource) - Get the resource into which the appointment is being dropped. -`IsDroppingToAllDay` - Gets a value indicating whether an appointment is being dropped into an all-day slot. +[IsDroppingToAllDay](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.AppointmentDropEventArgs.html#Syncfusion_Maui_Scheduler_AppointmentDropEventArgs_IsDroppingToAllDay) - Gets a value indicating whether an appointment is being dropped into an all-day slot. {% tabs %} {% highlight c# %} @@ -118,7 +118,7 @@ private void OnSchedulerAppointmentDrop(object? sender, AppointmentDropEventArgs ### Prevent dropping appointments into the all-day panel -You can prevent appointments from being dropped into the all-day panel by checking the `IsDroppingToAllDay` property in the `AppointmentDrop` event and canceling the operation. +You can prevent appointments from being dropped into the all-day panel by checking the [IsDroppingToAllDay](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.AppointmentDropEventArgs.html#Syncfusion_Maui_Scheduler_AppointmentDropEventArgs_IsDroppingToAllDay) property in the [AppointmentDrop](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SfScheduler.html#Syncfusion_Maui_Scheduler_SfScheduler_AppointmentDrop) event and canceling the operation. {% tabs %} {% highlight c# %} diff --git a/MAUI/Scheduler/images/month-view/appointment-indicator-size-maui-scheduler.png b/MAUI/Scheduler/images/month-view/appointment-indicator-size-maui-scheduler.png new file mode 100644 index 0000000000..0aa8ac891c Binary files /dev/null and b/MAUI/Scheduler/images/month-view/appointment-indicator-size-maui-scheduler.png differ diff --git a/MAUI/Scheduler/images/resource-view/resource-width-net-maui-scheduler.png b/MAUI/Scheduler/images/resource-view/resource-width-net-maui-scheduler.png new file mode 100644 index 0000000000..2604c38bc9 Binary files /dev/null and b/MAUI/Scheduler/images/resource-view/resource-width-net-maui-scheduler.png differ diff --git a/MAUI/Scheduler/images/resource-view/visible-resource-count-net-maui-scheduler.png b/MAUI/Scheduler/images/resource-view/visible-resource-count-net-maui-scheduler.png new file mode 100644 index 0000000000..1655b6523c Binary files /dev/null and b/MAUI/Scheduler/images/resource-view/visible-resource-count-net-maui-scheduler.png differ diff --git a/MAUI/Scheduler/localization.md b/MAUI/Scheduler/localization.md index ae0bccfab6..22b05b7c75 100644 --- a/MAUI/Scheduler/localization.md +++ b/MAUI/Scheduler/localization.md @@ -1,6 +1,6 @@ --- layout: post -title: Localization in .NET MAUI Scheduler control | Syncfusion® +title: Localization in .NET MAUI Scheduler control | Syncfusion® description: Learn here all about Localization support in Syncfusion® .NET MAUI Scheduler (SfScheduler) control and more. platform: maui control: SfScheduler @@ -9,7 +9,20 @@ documentation: ug # Localization in .NET MAUI Scheduler (SfScheduler) -Localization is the process of translating the application resources into different language for the specific cultures. The `SfScheduler` can be localized by adding `resource` file. +Localization is the process of translating the application resources into different language for the specific cultures. The `SfScheduler` can be localized by adding `resource` file. The SfScheduler allows you to localize the following built-in strings to suit your application’s language and culture: + +* Day +* Week +* WorkWeek +* Month +* TimelineDay +* TimelineWeek +* TimelineWorkWeek +* TimelineMonth +* Agenda +* Today +* NoEvents +* AllDay ## Setting CurrentUICulture to the application @@ -63,4 +76,7 @@ To localize the `Scheduler` based on `CurrentUICulture` using `resource` files, 6. Add the Name/Value pair in Resource Designer of `SfScheduler.fr-FR.resx` file and change its corresponding value to corresponding culture. - ![shows-the-added-resource-file-name-value-pair-in-the-resource-designer-in-maui-scheduler](images/localization/shows-the-added-resource-file-name-value-pair-in-the-resource-designer-in-maui-scheduler.png) \ No newline at end of file + ![shows-the-added-resource-file-name-value-pair-in-the-resource-designer-in-maui-scheduler](images/localization/shows-the-added-resource-file-name-value-pair-in-the-resource-designer-in-maui-scheduler.png) + + The complete sample can be downloaded from [GitHub](https://github.com/SyncfusionExamples/maui-scheduler-examples/tree/main/Localization). + \ No newline at end of file diff --git a/MAUI/Scheduler/month-view.md b/MAUI/Scheduler/month-view.md index a606e5d2c6..750d612967 100644 --- a/MAUI/Scheduler/month-view.md +++ b/MAUI/Scheduler/month-view.md @@ -85,7 +85,7 @@ this.Scheduler.MonthView.AppointmentIndicatorCount = 1; ## Appointment indicator size -The scheduler month view allows you to customize the size of the appointment indicator by using the `AppointmentIndicatorSize` property of the [MonthView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerMonthView.html). By default, the `AppointmentIndicatorSize` is set to 6d. +The scheduler month view allows you to customize the size of the appointment indicator by using the [AppointmentIndicatorSize](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerMonthView.html#Syncfusion_Maui_Scheduler_SchedulerMonthView_AppointmentIndicatorSize) property of the [MonthView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerMonthView.html). By default, the [AppointmentIndicatorSize](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerMonthView.html#Syncfusion_Maui_Scheduler_SchedulerMonthView_AppointmentIndicatorSize) is set to 6d. {% tabs %} {% highlight XAML hl_lines="5" %} @@ -107,6 +107,8 @@ this.Scheduler.MonthView.AppointmentIndicatorSize = 10; {% endhighlight %} {% endtabs %} +![change-appointment-indicator-size-in-maui-scheduler](images/month-view/appointment-indicator-size-maui-scheduler.png){:width="325" height="600" loading="lazy" .lazy .shadow-effect .section-padding .img-padding} + ## Hide leading and trailing dates The previous and next month dates from a Scheduler month view can be hidden by using the [ShowLeadingAndTrailingDates](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerMonthView.html#Syncfusion_Maui_Scheduler_SchedulerMonthView_ShowLeadingAndTrailingDates) property in the [MonthView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerMonthView.html). The `ShowLeadingAndTrailingDates` property defaults to `true.` diff --git a/MAUI/Scheduler/resource-view.md b/MAUI/Scheduler/resource-view.md index e907e46704..84ab6711bd 100644 --- a/MAUI/Scheduler/resource-view.md +++ b/MAUI/Scheduler/resource-view.md @@ -238,6 +238,8 @@ N> * When [`VisibleResourceCount`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_VisibleResourceCount) is set to 0, the resource view layout is removed, and only the plain Scheduler view is shown. * [`VisibleResourceCount`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_VisibleResourceCount) applies to the horizontal resource view on Windows and macOS, and to the timeline resource view on all platforms. When the value is -1 (default), the horizontal resource view displays three resources. In timeline resource views, the number of visible resource rows is determined by the minimum row height, and the auto row height. +![VisibleResourceCount in .NET MAUI Scheduler.](images/resource-view/visible-resource-count-net-maui-scheduler.png) + ## Resource Header Height in Days View In the day, week, and work week views, resources are arranged horizontally. The height of the resource headers can be customized using the [`ResourceHeaderHeight`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_ResourceHeaderHeight) property of the [`SchedulerResourceView`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_Resources) class. @@ -267,7 +269,7 @@ this.Scheduler.ResourceView.ResourceHeaderHeight = 100; ## Resource Header Width in Timeline View -In the timelineday, timelineweek, and timeline work week views, resources are arranged vertically. The width of the resource headers can be customized using the `ResourceHeaderWidth` property of the [`SchedulerResourceView`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_Resources) class. +In the timelineday, timelineweek, and timeline work week views, resources are arranged vertically. The width of the resource headers can be customized using the [ResourceHeaderWidth](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_ResourceHeaderWidth) property of the [`SchedulerResourceView`](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_Resources) class. {% tabs %} {% highlight xaml tabtitle="MainPage.xaml" hl_lines="3" %} @@ -290,6 +292,8 @@ this.Scheduler.ResourceView.ResourceHeaderWidth = 250; {% endhighlight %} {% endtabs %} +![Resource header width in .NET MAUI Scheduler.](images/resource-view/resource-width-net-maui-scheduler.png) + ## Resource minimum row height You can customize resource minimum row height of visible resources in timeline day, timeline week, timeline workweek and timeline month views by using the [MinimumRowHeight](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html#Syncfusion_Maui_Scheduler_SchedulerResourceView_MinimumRowHeight) property of [SchedulerResourceView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SchedulerResourceView.html) in [SfScheduler.](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Scheduler.SfScheduler.html) By default, resource row height will be auto-expanded from minimum height based on the appointment counts. diff --git a/MAUI/Segmented-Control/customization.md b/MAUI/Segmented-Control/customization.md index 1fc0c3a7d2..54f4dac8ab 100644 --- a/MAUI/Segmented-Control/customization.md +++ b/MAUI/Segmented-Control/customization.md @@ -439,7 +439,7 @@ Use the [SegmentTemplate](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Bu ## Customize selected segment item appearance using DataTemplate -Use the `IsSelected` property of `SfSegmentItem` to customize the selected segment item appearance. The following example code shows how to create a custom segmented control using a data template. +Use the [IsSelected](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SfSegmentItem.html#Syncfusion_Maui_Buttons_SfSegmentItem_IsSelected) property of [SfSegmentItem](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentTappedEventArgs.html#Syncfusion_Maui_Buttons_SegmentTappedEventArgs_SegmentItem) to customize the selected segment item appearance. The following example code shows how to create a custom segmented control using a data template. {% tabs %} {% highlight XAML %} @@ -523,6 +523,6 @@ public class TextColorConverter : IValueConverter {% endtabs %} N> -* The BindingContext of the `SegmentTemplate` is the `SfSegmentItem`. +* The BindingContext of the [SegmentTemplate](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SfSegmentedControl.html#Syncfusion_Maui_Buttons_SfSegmentedControl_SegmentTemplate) is the [SfSegmentItem](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentTappedEventArgs.html#Syncfusion_Maui_Buttons_SegmentTappedEventArgs_SegmentItem). ![Customization for the selected segment item in .NET MAUI Segmented control.](images/customization/selected-segment.png) \ No newline at end of file diff --git a/MAUI/Segmented-Control/events.md b/MAUI/Segmented-Control/events.md index 8f28d6c34c..d7e8b6f3cc 100644 --- a/MAUI/Segmented-Control/events.md +++ b/MAUI/Segmented-Control/events.md @@ -9,7 +9,7 @@ documentation: ug # Events in .NET MAUI Segmented Control (SfSegmentedControl) -The Segmented Control supports the `Tapped,` and `SelectionChanged` events to interact with .NET MAUI Segmented Control +The Segmented Control supports the [Tapped](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SfSegmentedControl.html#Syncfusion_Maui_Buttons_SfSegmentedControl_Tapped), and [SelectionChanged](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SfSegmentedControl.html#Syncfusion_Maui_Buttons_SfSegmentedControl_SelectionChanged) events to interact with .NET MAUI Segmented Control ## Tapped @@ -17,9 +17,9 @@ A Tapped event occurs, each time a segment tapped. Below is a list of the arguments: -* `Sender`: This contains the `SfSegmentedControl` object. +* `Sender`: This contains the [SfSegmentedControl](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SfSegmentedControl.html#Syncfusion_Maui_Buttons_SfSegmentedControl__ctor) object. -* `Tapped`: The tapped action performed on an Segment can be found in the `SegmentTappedEventArgs`, you can see details about the `SegmentItem`. +* `Tapped`: The tapped action performed on an Segment can be found in the [SegmentTappedEventArgs](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentTappedEventArgs.html), you can see details about the [SegmentItem](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentTappedEventArgs.html#Syncfusion_Maui_Buttons_SegmentTappedEventArgs_SegmentItem). ## SelectionChanged diff --git a/MAUI/Segmented-Control/selection.md b/MAUI/Segmented-Control/selection.md index 235682bc54..e0a4e634fe 100644 --- a/MAUI/Segmented-Control/selection.md +++ b/MAUI/Segmented-Control/selection.md @@ -215,11 +215,11 @@ public partial class MainPage : ContentPage ## Selection Mode -You can select the segment item by tapping the item in the Segmented Control. SfSegmentedControl provides two types of modes such as `Single` and `SingleDeselect`. The default `SelectionMode` is `Single`. +You can select the segment item by tapping the item in the Segmented Control. SfSegmentedControl provides two types of modes such as [Single](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentSelectionMode.html) and [SingleDeselect](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentSelectionMode.html). The default [SelectionMode](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentSelectionMode.html) is `Single`. ### Single Selection -The Single selection can be performed in the `Segmented Control` by setting the `SelectionMode` property to `Single`. In this selection, you can select a single item at a time in the segmented control. +The Single selection can be performed in the [Segmented Control](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SfSegmentedControl.html) by setting the [SelectionMode](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentSelectionMode.html) property to [Single](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Buttons.SegmentSelectionMode.html). In this selection, you can select a single item at a time in the segmented control. {% tabs %} {% highlight XAML %} diff --git a/MAUI/TabView/Tab-Item-Customization.md b/MAUI/TabView/Tab-Item-Customization.md index 74ea655426..b4d8ac0960 100644 --- a/MAUI/TabView/Tab-Item-Customization.md +++ b/MAUI/TabView/Tab-Item-Customization.md @@ -583,4 +583,55 @@ stackLayout.Children.Add(tabView); this.Content = stackLayout; {% endhighlight %} +{% endtabs %} + +## Disable ripple effect on item click + +The [EnableRippleAnimation](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html#Syncfusion_Maui_TabView_SfTabView_EnableRippleAnimation) property of the [SfTabView](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html) allows you to enable or disable the ripple animation for tab headers. This animation provides visual feedback when a tab header is tapped. The default value of the `EnableRippleAnimation` property is `true`. + +{% tabs %} + +{% highlight xaml %} + + + + +{% endhighlight %} + +{% highlight C# %} +// Create an instance of the SfTabView control +SfTabView tabView = new SfTabView(); + +// Disable the ripple animation +tabView.EnableRippleAnimation = false; + +{% endhighlight %} + +{% endtabs %} + +## How to + +### Disable hover effect on tab item + +To disable the hover effect when the mouse pointer is over a [TabItem](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabItem.html) header, set color value `Transparent` to the built-in key `SfTabViewHoverBackground`. + +{% tabs %} + +{% highlight xaml %} + + + + Transparent + + + + + + + + +{% endhighlight %} + {% endtabs %} \ No newline at end of file diff --git a/MAUI/Themes/Keys.md b/MAUI/Themes/Keys.md index cc950a2cc1..18e3d301be 100644 --- a/MAUI/Themes/Keys.md +++ b/MAUI/Themes/Keys.md @@ -17553,7 +17553,7 @@ This page lists the keys associated with each control and the respective UI elem - + SfTabViewStyles

@@ -17961,6 +17961,18 @@ This page lists the keys associated with each control and the respective UI elem
+ + + SfTabViewHoverBackground +
+
+ + + Hover BackgroundColor of the SfTabItem. +
+
+ + ## SfTextInputLayout diff --git a/MAUI/TimePicker/images/customizations/maui-time-picker-set-column-header-text.png b/MAUI/TimePicker/images/customizations/maui-time-picker-set-column-header-text.png index 97b4576e8d..814371c157 100644 Binary files a/MAUI/TimePicker/images/customizations/maui-time-picker-set-column-header-text.png and b/MAUI/TimePicker/images/customizations/maui-time-picker-set-column-header-text.png differ diff --git a/MAUI/TimePicker/images/intervals/maui-time-picker-millisecond-interval.png b/MAUI/TimePicker/images/intervals/maui-time-picker-millisecond-interval.png index 8a2dc38209..ad50bf590c 100644 Binary files a/MAUI/TimePicker/images/intervals/maui-time-picker-millisecond-interval.png and b/MAUI/TimePicker/images/intervals/maui-time-picker-millisecond-interval.png differ diff --git a/maui-toc.html b/maui-toc.html index 9de3d3ebf5..30dc9d47e4 100644 --- a/maui-toc.html +++ b/maui-toc.html @@ -12,6 +12,12 @@
  • System Requirements
  • Demos
  • Material Icons
  • +
  • AI Coding Assistant + +
  • Installation @@ -1404,6 +1413,21 @@
  • Release Notes - +