Recommendation on how do I should “manually” draw Canvas contents during window resize?

  Kiến thức lập trình

It’s going to be a while before I understand what is going on under the hood relying on the higher level features of the WPF object model and run-time engine, so in the interim I thought I would try to be more in control of the user interface. I am trying to draw my Canvas contents using the DeviceContext, which seems to work, but I don’t even understand what is going on under the hood for this.

The text (some Canvas coordinates) draws, but while the window is being resized, how do I, flicker-free, redraw the text with the background staying the background color for the whole Canvas. Right now, only my original rectangle stays LightSteelBlue and the text doesn’t move at all—which is supposed to be drawn at coordinates determined as a percentage of the Canvas size.

How is my understanding of the paradigm I am trying to use not yet good enough? I could try to do this the normal(?) way (without using the device context), but doing things like erasing to the background color seemed to be even deeper into understanding WPF. Ultimately, I need to be able to draw lines, bitmaps, and text via pixel-level accuracy, such as if I wanted to draw a couple lines and have them look like one thick line.

using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;

namespace Greg2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.Height = 500;
            this.Width = 500;
            Canvas myCanvas = new MWCanvas();
            myCanvas.Width = this.Width;
            myCanvas.Height = this.Height;
            myCanvas.Background = Brushes.LightSteelBlue;
            this.Content = myCanvas;

            InitializeComponent();
        }

        public class MWCanvas : Canvas {
            public MWCanvas()
            {
                DefaultStyleKey = typeof(MWCanvas);
            }

            protected override void OnRender(System.Windows.Media.DrawingContext dc)
            {
                base.OnRender(dc);
                double canvasWidth = this.Width;
                double canvasHeight = this.Height;

                for (double dY = 0.0; dY < 1.0; dY += 0.1)
                {
                    for (double dX = 0; dX < 1.0; dX += 0.1)
                    {

                        String s = String.Format("{0},{1}", dX, dY);

                        FormattedText formattedText = new FormattedText(s,
                            CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), 12, Brushes.Black, VisualTreeHelper.GetDpi(this).PixelsPerDip);

                        // Draw the formatted text string to the DrawingContext of the Canvas control.
                        dc.DrawText(formattedText, new Point(VirtualToActualX(dX), VirtualToActualY(dY)));
                    } // for x
                } // for y
           } // OnRender()

            protected double VirtualToActualX(double dXPercent)
            {
                String sNotif = String.Format("dXPercent={0}, this.Width={1}", dXPercent, this.Width);
                Trace.WriteLine(sNotif);
                return dXPercent * this.Width;
            }
            protected double VirtualToActualY(double dYPercent)
            {
                String sNotif = String.Format("dYPercent={0}, this.Width={1}", dYPercent, this.Height);
                Trace.WriteLine(sNotif);
                return dYPercent * this.Height;
            }

        } // class MWCanvas

    }

}

I tried drawing a LightSteelBlue rectangle over the whole Canvas before drawing the text, but it didn’t do anything.

New contributor

GregJ7 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT