diff --git a/components/MarkdownTextBlock/src/MarkdownParsedEventArgs.cs b/components/MarkdownTextBlock/src/MarkdownParsedEventArgs.cs
new file mode 100644
index 000000000..8f96eb19c
--- /dev/null
+++ b/components/MarkdownTextBlock/src/MarkdownParsedEventArgs.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Markdig.Syntax;
+
+namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock;
+
+public sealed class MarkdownParsedEventArgs : EventArgs
+{
+    public MarkdownDocument Document { get; }
+    public MarkdownParsedEventArgs(MarkdownDocument document)
+    {
+        Document = document;
+    }
+}
diff --git a/components/MarkdownTextBlock/src/MarkdownTextBlock.Events.cs b/components/MarkdownTextBlock/src/MarkdownTextBlock.Events.cs
new file mode 100644
index 000000000..5faf4e48c
--- /dev/null
+++ b/components/MarkdownTextBlock/src/MarkdownTextBlock.Events.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock;
+
+partial class MarkdownTextBlock
+{
+    /// <summary>
+    /// Event raised when a markdown link is clicked.
+    /// </summary>
+    public event EventHandler<LinkClickedEventArgs>? OnLinkClicked;
+
+    /// <summary>
+    /// Event raised when markdown is done parsing, with a complete MarkdownDocument.
+    /// It is always raised before the control renders the document.
+    /// </summary>
+    public event EventHandler<MarkdownParsedEventArgs>? OnMarkdownParsed;
+}
diff --git a/components/MarkdownTextBlock/src/MarkdownTextBlock.xaml.cs b/components/MarkdownTextBlock/src/MarkdownTextBlock.xaml.cs
index fb3e6f4aa..b9a07bc2f 100644
--- a/components/MarkdownTextBlock/src/MarkdownTextBlock.xaml.cs
+++ b/components/MarkdownTextBlock/src/MarkdownTextBlock.xaml.cs
@@ -21,6 +21,43 @@ public partial class MarkdownTextBlock : Control
     private MyFlowDocument _document;
     private WinUIRenderer? _renderer;
 
+    private static readonly DependencyProperty ConfigProperty = DependencyProperty.Register(
+        nameof(Config),
+        typeof(MarkdownConfig),
+        typeof(MarkdownTextBlock),
+        new PropertyMetadata(null, OnConfigChanged)
+    );
+
+    private static readonly DependencyProperty TextProperty = DependencyProperty.Register(
+        nameof(Text),
+        typeof(string),
+        typeof(MarkdownTextBlock),
+        new PropertyMetadata(null, OnTextChanged));
+
+    private static readonly DependencyProperty MarkdownDocumentProperty = DependencyProperty.Register(
+        nameof(MarkdownDocument),
+        typeof(MarkdownDocument),
+        typeof(MarkdownTextBlock),
+        new PropertyMetadata(null));
+
+    public MarkdownConfig Config
+    {
+        get => (MarkdownConfig)GetValue(ConfigProperty);
+        set => SetValue(ConfigProperty, value);
+    }
+
+    public string Text
+    {
+        get => (string)GetValue(TextProperty);
+        set => SetValue(TextProperty, value);
+    }
+
+    public MarkdownDocument? MarkdownDocument
+    {
+        get => (MarkdownDocument)GetValue(MarkdownDocumentProperty);
+        private set => SetValue(MarkdownDocumentProperty, value);
+    }
+    
     public event EventHandler<LinkClickedEventArgs>? OnLinkClicked;
 
     internal void RaiseLinkClickedEvent(Uri uri) => OnLinkClicked?.Invoke(this, new LinkClickedEventArgs(uri));
@@ -89,6 +126,7 @@ private void ApplyText(bool rerender)
             if (!string.IsNullOrEmpty(Text))
             {
                 var parsedMarkdown = Markdown.Parse(Text, _pipeline);
+                OnMarkdownParsed?.Invoke(this, new MarkdownParsedEventArgs(this.MarkdownDocument));
                 this.MarkdownDocument = parsedMarkdown;
                 _renderer.Render(parsedMarkdown);
             }