how to port DrawingBrush stuff from WPF to WinUI 3?

Mahdi Hosseini 135 Reputation points
2023-12-22T07:56:13.2366667+00:00

I am trying to port a WPF control to WinUI.Most of the work is done and only the main work remains.

The goal is to create a watermark control.

Watermark

i dont know how to port this code into winui, there is no DrawingBrush class:

there is some error for:

DrawingBrush

RotateTransform

VisualBrush

GeometryDrawing

new Rect(markSize)

_brush = new DrawingBrush
{
    ViewportUnits = BrushMappingMode.Absolute,
    Stretch = Stretch.Uniform,
    TileMode = TileMode.Tile,
    Transform = new RotateTransform(Angle),
    Drawing = new GeometryDrawing
    {
        Brush = new VisualBrush(new Border
        {
            Background = Brushes.Transparent,
            Padding = MarkMargin,
            Child = presenter
        }),
        Geometry = new RectangleGeometry(new Rect(markSize))
    },
    Viewport = new Rect(markSize)
};
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,706 questions
Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
747 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,574 questions
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 16,391 Reputation points Microsoft Vendor
    2023-12-27T09:14:25.6566667+00:00

    Hi @Mahdi Hosseini ,

    Welcome to Microsoft Q&A!

    I'll share my solution here, it may not be elegant enough.

    1. Install System.Drawing.Common in NuGet Manager, use Graphics.DrawString to draw text.
    2. Rotate the image.
    3. Use the image in ImageBrush , fill it in a layout.
    <?xml version="1.0" encoding="utf-8"?>
    <Window
        x:Class="Winui3WaterMark.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Winui3WaterMark"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="Black" BorderThickness="1">
            <Rectangle x:Name="rectangle" Height="500" Width="500">
                <Rectangle.Fill>
                    <ImageBrush ImageSource="{x:Bind imgTest.Source}" Stretch="None"/>
                </Rectangle.Fill>
            </Rectangle>
        </StackPanel>
    </Window>
    
    

    using ABI.Windows.Foundation;
    using Microsoft.UI.Xaml;
    using Microsoft.UI.Xaml.Controls;
    using Microsoft.UI.Xaml.Controls.Primitives;
    using Microsoft.UI.Xaml.Data;
    using Microsoft.UI.Xaml.Input;
    using Microsoft.UI.Xaml.Media;
    using Microsoft.UI.Xaml.Media.Imaging;
    using Microsoft.UI.Xaml.Navigation;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Reflection.Metadata;
    using System.Runtime.InteropServices.WindowsRuntime;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    
    // To learn more about WinUI, the WinUI project structure,
    // and more about our project templates, see: http://aka.ms/winui-project-info.
    
    namespace Winui3WaterMark
    {
        /// <summary>
        /// An empty window that can be used on its own or navigated to within a Frame.
        /// </summary>
        public sealed partial class MainWindow : Window
        {
            public Microsoft.UI.Xaml.Controls.Image imgTest;
            public MainWindow()
            {
                this.InitializeComponent();
    
                imgTest=new Microsoft.UI.Xaml.Controls.Image();
    
                var bmp = ConvertTextToImage("WaterMark", "Calibri", 10, Color.Empty, Color.HotPink, 1000, 2000);
    
                BitmapImage bitmapImage = new BitmapImage();
    
                using (MemoryStream stream = new MemoryStream())
                {
          
                    bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
                    stream.Position = 0;
                    bitmapImage.SetSource(stream.AsRandomAccessStream());
                }
                imgTest.Source = bitmapImage;
            }
        
            public Bitmap ConvertTextToImage(string txt, string fontname, int fontsize, Color bgcolor, Color fcolor, int width, int Height)
            {
                Bitmap bmp = new Bitmap(width, Height);
    
                //a way to get the width of string
                SizeF size;
                using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(new Bitmap(1, 1)))
                {
                     size = graphics.MeasureString(txt, new Font(fontname, fontsize, FontStyle.Regular, GraphicsUnit.Point));
                }
    
                //draw text
                using (Graphics graphics = Graphics.FromImage(bmp))
                {
    
                    Font font = new Font(fontname, fontsize);
    
                    //In order to avoid blank areas after rotation, expand the drawing range
                    graphics.FillRectangle(new SolidBrush(bgcolor), -size.Width, -font.Height, width+2*size.Width, Height+2*font.Height);
    
                    for (int i = 0; i < Height/ font.Height; i++) 
                    {
                        for (int j = -2; j< width/ size.Width; j++ ) 
                        {
                            graphics.DrawString(txt, font, new SolidBrush(fcolor), j* size.Width, i * font.Height);
                        }
                       
                    }   
                   
                    graphics.Flush();
                    font.Dispose();
                    graphics.Dispose();
    
                }
    
                //rotate the bitmap
                Bitmap returnBitmap = new Bitmap(bmp.Width, bmp.Height);
    
                using (Graphics g = Graphics.FromImage(returnBitmap))
                {
                    g.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
                    g.RotateTransform(15);
                    g.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
                    g.DrawImage(bmp, new System.Drawing.Point(0, 0));
                }
    
                return returnBitmap;
            }
    
           
        }
    }
    
    

    User's image

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful