Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- 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. -->
<!-- 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. -->
<local:MarkdownTextBlockCustomThemeSampleBase x:Class="MarkdownTextBlockExperiment.Samples.MarkdownTextBlockCustomThemeSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand All @@ -7,7 +7,6 @@
xmlns:local="using:MarkdownTextBlockExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<ScrollViewer>
<controls:MarkdownTextBlock x:Name="MarkdownTextBlock"
Margin="12"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace MarkdownTextBlockExperiment.Samples;
/// <summary>
/// A sample demonstrating custom theming options for the MarkdownTextBlock control with live editing.
/// </summary>
///
[ToolkitSample(id: nameof(MarkdownTextBlockCustomThemeSample), "Custom Theme", description: "A sample showcasing custom theming options with live editing for headings, code blocks, quotes, tables, and more.")]
public sealed partial class MarkdownTextBlockCustomThemeSample : MarkdownTextBlockCustomThemeSampleBase
{
Expand Down Expand Up @@ -40,6 +41,10 @@ This sample demonstrates the **custom theming** capabilities of the `MarkdownTex

The image above automatically scales to respect the max width setting while maintaining its aspect ratio. Text continues to flow seamlessly below it.

![Shortcut Conflict](https://devblogs.microsoft.com/commandline/wp-content/uploads/sites/33/2025/09/ShortcutConflict.png)

Here's another image that also responds to the image styling settings.

## Code Blocks

```csharp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- 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. -->
<!-- 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. -->
<Page x:Class="MarkdownTextBlockExperiment.Samples.MarkdownTextBlockExampleSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- 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. -->
<!-- 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. -->
<Page x:Class="MarkdownTextBlockExperiment.Samples.MarkdownTextBlockLiveEditorSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand Down
26 changes: 13 additions & 13 deletions components/MarkdownTextBlock/src/MarkdownThemes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ public sealed class MarkdownThemes : DependencyObject

public FontWeight H1FontWeight { get; set; } = FontWeights.SemiBold;

public FontWeight H2FontWeight { get; set; } = FontWeights.Normal;
public FontWeight H2FontWeight { get; set; } = FontWeights.SemiBold;

public FontWeight H3FontWeight { get; set; } = FontWeights.Normal;
public FontWeight H3FontWeight { get; set; } = FontWeights.SemiBold;

public FontWeight H4FontWeight { get; set;} = FontWeights.Normal;
public FontWeight H4FontWeight { get; set;} = FontWeights.SemiBold;

public FontWeight H5FontWeight { get; set; } = FontWeights.Normal;
public FontWeight H5FontWeight { get; set; } = FontWeights.SemiBold;

public FontWeight H6FontWeight { get; set; } = FontWeights.Normal;
public FontWeight H6FontWeight { get; set; } = FontWeights.SemiBold;

public Thickness H1Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
public Thickness H2Margin { get; set; } = new(left: 0, top: 16, right: 0, bottom: 0);
Expand All @@ -64,10 +64,10 @@ public sealed class MarkdownThemes : DependencyObject

public Brush TableHeadingBackground { get; set; } = Extensions.GetAccentColorBrush(Windows.UI.ViewManagement.UIColorType.AccentLight3);

public Brush InlineCodeBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
public Brush InlineCodeBackground { get; set; } = (Brush)Application.Current.Resources["CardBackgroundFillColorSecondaryBrush"];
public Brush InlineCodeForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];

public Brush InlineCodeBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
public Brush InlineCodeBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];

public Thickness InlineCodeBorderThickness { get; set; } = new (1);

Expand All @@ -83,8 +83,8 @@ public sealed class MarkdownThemes : DependencyObject

// Legacy parity properties (new)
// Code block styling
public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
public Brush CodeBlockBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
public Brush CodeBlockBackground { get; set; } = (Brush)Application.Current.Resources["CardBackgroundFillColorSecondaryBrush"];
public Brush CodeBlockBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
public Thickness CodeBlockBorderThickness { get; set; } = new Thickness(1);
public Thickness CodeBlockPadding { get; set; } = new Thickness(8);
public Thickness CodeBlockMargin { get; set; } = new Thickness(0, 8, 0, 8);
Expand All @@ -93,7 +93,7 @@ public sealed class MarkdownThemes : DependencyObject
public CornerRadius CodeBlockCornerRadius { get; set; } = new CornerRadius(4);

// Horizontal rule
public Brush HorizontalRuleBrush { get; set; } = new SolidColorBrush(Colors.Gray);
public Brush HorizontalRuleBrush { get; set; } = (Brush)Application.Current.Resources["DividerStrokeColorDefaultBrush"];
public double HorizontalRuleThickness { get; set; } = 1.0;
public Thickness HorizontalRuleMargin { get; set; } = new Thickness(0, 12, 0, 12);

Expand Down Expand Up @@ -122,12 +122,12 @@ public sealed class MarkdownThemes : DependencyObject
public Stretch ImageStretch { get; set; } = Stretch.Uniform;

// Table styling
public Brush TableBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
public Brush TableBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
public double TableBorderThickness { get; set; } = 1;
public Thickness TableCellPadding { get; set; } = new Thickness(4);
public Thickness TableMargin { get; set; } = new Thickness(0, 10, 0, 10);
public Thickness TableMargin { get; set; } = new Thickness(0, 8, 0, 8);

// YAML / not currently used - placeholders for parity
public Brush YamlBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);
public Brush YamlBorderBrush { get; set; } = (Brush)Application.Current.Resources["CardStrokeColorDefaultBrush"];
public Thickness YamlBorderThickness { get; set; } = new Thickness(1);
}
63 changes: 24 additions & 39 deletions components/MarkdownTextBlock/src/TextElements/MyImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,53 +137,38 @@ private async void LoadImage(object sender, RoutedEventArgs e)
await bitmap.SetSourceAsync(stream);
}
_image.Source = bitmap;
_image.Width = bitmap.PixelWidth == 0 ? bitmap.DecodePixelWidth : bitmap.PixelWidth;
_image.Height = bitmap.PixelHeight == 0 ? bitmap.DecodePixelHeight : bitmap.PixelHeight;

// Don't set fixed Width/Height - let layout system handle it
// Store natural dimensions for MaxWidth/MaxHeight constraints
double naturalWidth = bitmap.PixelWidth == 0 ? bitmap.DecodePixelWidth : bitmap.PixelWidth;
double naturalHeight = bitmap.PixelHeight == 0 ? bitmap.DecodePixelHeight : bitmap.PixelHeight;

// Use natural size as max constraint so image doesn't upscale
_image.MaxWidth = naturalWidth;
_image.MaxHeight = naturalHeight;
}

_loaded = true;
}

// Determine the actual image dimensions
double actualWidth = _precedentWidth != 0 ? _precedentWidth : _image.Width;
double actualHeight = _precedentHeight != 0 ? _precedentHeight : _image.Height;

// Apply max constraints and calculate the final size
// When using Uniform stretch with max constraints, we need to calculate
// the actual rendered size to avoid gaps
double finalWidth = actualWidth;
double finalHeight = actualHeight;

bool hasMaxWidth = _themes.ImageMaxWidth > 0;
bool hasMaxHeight = _themes.ImageMaxHeight > 0;

if (hasMaxWidth || hasMaxHeight)
// Apply precedent (markdown-specified) dimensions if provided
if (_precedentWidth != 0)
{
double scaleX = hasMaxWidth && actualWidth > _themes.ImageMaxWidth
? _themes.ImageMaxWidth / actualWidth
: 1.0;
double scaleY = hasMaxHeight && actualHeight > _themes.ImageMaxHeight
? _themes.ImageMaxHeight / actualHeight
: 1.0;

// For Uniform stretch, use the smaller scale to maintain aspect ratio
if (_themes.ImageStretch == Stretch.Uniform || _themes.ImageStretch == Stretch.UniformToFill)
{
double uniformScale = Math.Min(scaleX, scaleY);
finalWidth = actualWidth * uniformScale;
finalHeight = actualHeight * uniformScale;
}
else
{
// For other stretch modes, apply constraints independently
finalWidth = actualWidth * scaleX;
finalHeight = actualHeight * scaleY;
}
_image.MaxWidth = _precedentWidth;
}
if (_precedentHeight != 0)
{
_image.MaxHeight = _precedentHeight;
}

_image.Width = finalWidth;
_image.Height = finalHeight;
// Apply theme constraints - these override natural/precedent if smaller
if (_themes.ImageMaxWidth > 0 && _themes.ImageMaxWidth < _image.MaxWidth)
{
_image.MaxWidth = _themes.ImageMaxWidth;
}
if (_themes.ImageMaxHeight > 0 && _themes.ImageMaxHeight < _image.MaxHeight)
{
_image.MaxHeight = _themes.ImageMaxHeight;
}
_image.Stretch = _themes.ImageStretch;
}
catch (Exception) { }
Expand Down
Loading