# rich-text-editor-notes

> Rich text editor manages a notes list with add, delete, select, and save timestamp via two-way binding.

**Framework:** maui  **Component:** rich-text-editor  **Variant:** notes

## Get this item

**If you are an agent, fetch the JSON.** Source is inlined, so one request is enough and no tooling is required:

```
GET https://ai.syncfusion.com/r/maui/rich-text-editor-notes.json
```

**Install Package(s)**

```bash
dotnet add package Syncfusion.Maui.RichTextEditor
```

**Notes**

- Syncfusion release: 2026 Volume 2 (v34.1.29)
- The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md

## Source files

### src/components/rich-text-editor-notes/RichTextEditor.xaml

```xaml
﻿<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:syncfusion="clr-namespace:Syncfusion.Maui.PdfViewer;assembly=Syncfusion.Maui.PdfViewer"
             xmlns:rte="clr-namespace:Syncfusion.Maui.RichTextEditor;assembly=Syncfusion.Maui.RichTextEditor"
             x:Class="MauiApp1.MainPage">

    <Grid ColumnDefinitions="280, *"
          ColumnSpacing="12"
          Padding="12">

        <!-- LEFT: notes list with Add/Delete actions -->
        <Border Grid.Column="0"
                Stroke="LightGrey"
                StrokeShape="RoundRectangle 12"
                StrokeThickness="1"
                Padding="8">
            <Grid RowDefinitions="Auto, *, Auto" RowSpacing="8">

                <Label Grid.Row="0"
                       Text="My Notes"
                       FontSize="18"
                       FontAttributes="Bold"
                       Padding="4,0,0,0" />

                <CollectionView x:Name="NotesList"
                                Grid.Row="1"
                                SelectionMode="Single"
                                SelectionChanged="OnNoteSelectedChanged">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <Border Padding="10"
                                    Margin="2"
                                    Stroke="Transparent"
                                    BackgroundColor="{AppThemeBinding Light=#F4F4F8, Dark=#2A2A2A}"
                                    StrokeShape="RoundRectangle 8">
                                <VerticalStackLayout Spacing="2">
                                    <Label Text="{Binding Title}"
                                           FontSize="14"
                                           FontAttributes="Bold"
                                           LineBreakMode="TailTruncation" />
                                    <Label Text="{Binding Author, StringFormat='by {0}'}"
                                           FontSize="11"
                                           Opacity="0.7" />
                                    <Label Text="{Binding CreatedAt, StringFormat='{0:MMM d, yyyy h:mm tt}'}"
                                           FontSize="10"
                                           Opacity="0.5" />
                                </VerticalStackLayout>
                            </Border>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

                <HorizontalStackLayout Grid.Row="2" Spacing="8">
                    <Button Text="Add"
                            Clicked="OnAddNoteClicked" />
                    <Button Text="Delete"
                            Clicked="OnDeleteNoteClicked" />
                </HorizontalStackLayout>
            </Grid>
        </Border>

        <!-- RIGHT: RichTextEditor showing the selected note's HtmlContent -->
        <Border Grid.Column="1"
                Stroke="LightGrey"
                StrokeShape="RoundRectangle 12"
                StrokeThickness="1"
                Padding="0">
            <Grid RowDefinitions="Auto, *" RowSpacing="0">

                <Grid Grid.Row="0"
                      Padding="12,8"
                      ColumnDefinitions="*, Auto"
                      BackgroundColor="{AppThemeBinding Light=#F8F8FB, Dark=#1F1F1F}">
                    <VerticalStackLayout Grid.Column="0" Spacing="2">
                        <Label x:Name="SelectedTitleLabel"
                               Text="No note selected"
                               FontSize="16"
                               FontAttributes="Bold" />
                        <Label x:Name="SelectedAuthorLabel"
                               FontSize="12"
                               Opacity="0.7" />
                    </VerticalStackLayout>

                    <Button Grid.Column="1"
                            Text="Save"
                            Clicked="OnSaveNoteClicked" />
                </Grid>

                <rte:SfRichTextEditor x:Name="NoteEditor"
                                      Grid.Row="1"
                                      Placeholder="Start typing your note..."
                                      ToolbarPosition="Bottom"
                                      VerticalOptions="Fill">
                    <rte:SfRichTextEditor.ToolbarItems>
                        <rte:RichTextToolbarItem Type="Bold" />
                        <rte:RichTextToolbarItem Type="Italic" />
                        <rte:RichTextToolbarItem Type="Underline" />
                        <rte:RichTextToolbarItem Type="Separator" />
                        <rte:RichTextToolbarItem Type="FontFamily" />
                        <rte:RichTextToolbarItem Type="FontSize" />
                        <rte:RichTextToolbarItem Type="Separator" />
                        <rte:RichTextToolbarItem Type="BulletList" />
                        <rte:RichTextToolbarItem Type="NumberList" />
                        <rte:RichTextToolbarItem Type="Separator" />
                        <rte:RichTextToolbarItem Type="Alignment" />
                        <rte:RichTextToolbarItem Type="ParagraphFormat" />
                        <rte:RichTextToolbarItem Type="Separator" />
                        <rte:RichTextToolbarItem Type="Hyperlink" />
                        <rte:RichTextToolbarItem Type="Image" />
                    </rte:SfRichTextEditor.ToolbarItems>
                </rte:SfRichTextEditor>
            </Grid>
        </Border>
    </Grid>

</ContentPage>

```

### src/components/rich-text-editor-notes/RichTextEditor.xaml.cs

```cs
﻿using System.Collections.ObjectModel;
using System.ComponentModel;

namespace MauiApp1
{
    public partial class MainPage : ContentPage
    {
        private readonly ObservableCollection<NoteModel> notes = new();
        private NoteModel? selectedNote;
        private bool suppressEditorSync;
        public MainPage()
        {
            InitializeComponent();
            LoadSeedNotes();
            NoteEditor.PropertyChanged += OnEditorPropertyChanged;

            // Push the initial collection to the CollectionView.
            NotesList.ItemsSource = notes;
            selectedNote = notes.Count > 0 ? notes[0] : null;
            NotesList.SelectedItem = selectedNote;
            UpdateEditorFromSelection();
        }
        private void LoadSeedNotes()
        {
            notes.Add(new NoteModel(
                "Welcome to Notes",
                "Syncfusion",
                "<p><strong>Welcome!</strong></p>" +
                "<p>This is a <em>simple</em> RichTextEditor sample showing how to bind " +
                "HTML content to the <strong>SfRichTextEditor</strong> control.</p>" +
                "<ul><li>Bold, italic, underline</li><li>Bullet and numbered lists</li>" +
                "<li>Hyperlinks and images</li></ul>"));

            notes.Add(new NoteModel(
                "Project Kickoff",
                "Ivy",
                "<p>Project kickoff is scheduled for <strong>August 19</strong>.</p>" +
                "<p>Deliverables are due by <em>September 30</em>.</p>"));

            notes.Add(new NoteModel(
                "Meeting Summary",
                "Frank",
                "<p><u>Weekly Sync</u></p>" +
                "<ol><li>Reviewed last week's progress</li>" +
                "<li>Discussed blockers for the RichTextEditor toolbar</li>" +
                "<li>Planned next iteration</li></ol>"));
        }

        // --- Editor <-> Model sync --------------------------------------------

        private void OnEditorPropertyChanged(object? sender, PropertyChangedEventArgs e)
        {
            // SfRichTextEditor raises PropertyChanged for "HtmlText" whenever
            // the user edits the document. Mirror that into the currently
            // selected note so Save / Delete see the latest content.
            if (suppressEditorSync) return;
            if (e.PropertyName != nameof(Syncfusion.Maui.RichTextEditor.SfRichTextEditor.HtmlText)) return;
            if (selectedNote is null) return;

            selectedNote.HtmlContent = NoteEditor.HtmlText ?? string.Empty;
        }

        // --- CollectionView selection ----------------------------------------

        private void OnNoteSelectedChanged(object? sender, SelectionChangedEventArgs e)
        {
            selectedNote = NotesList.SelectedItem as NoteModel;
            UpdateEditorFromSelection();
        }

        private void UpdateEditorFromSelection()
        {
            // Header labels in the right-hand panel.
            if (selectedNote is null)
            {
                SelectedTitleLabel.Text = "No note selected";
                SelectedAuthorLabel.Text = string.Empty;
            }
            else
            {
                SelectedTitleLabel.Text = selectedNote.Title;
                SelectedAuthorLabel.Text = string.IsNullOrEmpty(selectedNote.Author)
                    ? string.Empty
                    : $"by {selectedNote.Author}";
            }

            // Push the selected note's HTML into the editor without echoing
            // that assignment back into the model.
            suppressEditorSync = true;
            try
            {
                NoteEditor.HtmlText = selectedNote?.HtmlContent ?? string.Empty;
            }
            finally
            {
                suppressEditorSync = false;
            }
        }

        // --- Command handlers (XAML Clicked events) ---------------------------

        private void OnAddNoteClicked(object? sender, EventArgs e)
        {
            // Capture any in-flight edits before mutating the collection.
            if (selectedNote is not null)
            {
                selectedNote.HtmlContent = NoteEditor.HtmlText ?? selectedNote.HtmlContent;
            }

            var note = new NoteModel("New Note", "You", "<p></p>");
            notes.Add(note);
            selectedNote = note;
            NotesList.SelectedItem = note;
            UpdateEditorFromSelection();
        }

        private void OnDeleteNoteClicked(object? sender, EventArgs e)
        {
            if (selectedNote is null) return;

            var index = notes.IndexOf(selectedNote);
            notes.Remove(selectedNote);

            if (notes.Count == 0)
            {
                selectedNote = null;
                NotesList.SelectedItem = null;
            }
            else
            {
                var newIndex = Math.Max(0, Math.Min(index, notes.Count - 1));
                var next = notes[newIndex];
                selectedNote = next;
                NotesList.SelectedItem = next;
            }

            UpdateEditorFromSelection();
        }

        private void OnSaveNoteClicked(object? sender, EventArgs e)
        {
            // Save = "bump the timestamp on the currently selected note".
            if (selectedNote is null) return;
            if (!suppressEditorSync)
            {
                selectedNote.HtmlContent = NoteEditor.HtmlText ?? selectedNote.HtmlContent;
            }
            selectedNote.CreatedAt = DateTime.Now;

            // Force the list to re-template so the per-row CreatedAt label
            // shows the new timestamp. Re-assigning ItemsSource is the
            // simplest way without INotifyPropertyChanged on the model.
            NotesList.ItemsSource = null;
            NotesList.ItemsSource = notes;
            NotesList.SelectedItem = selectedNote;
            UpdateEditorFromSelection();
        }
    }

    public class NoteModel
    {
        /// <summary>Display title for the note.</summary>
        public string Title { get; set; } = string.Empty;

        /// <summary>Author name for the note.</summary>
        public string Author { get; set; } = string.Empty;

        /// <summary>Timestamp the note was created / last saved.</summary>
        public DateTime CreatedAt { get; set; } = DateTime.Now;

        /// <summary>HTML body of the note, bound two-way to the editor.</summary>
        public string HtmlContent { get; set; } = string.Empty;

        public NoteModel() { }

        public NoteModel(string title, string author, string htmlContent)
        {
            Title = title;
            Author = author;
            HtmlContent = htmlContent;
            CreatedAt = DateTime.Now;
        }
    }
}

```
