Line is not displayed on startup but becomes visib

2019-09-18 03:04发布

问题:

I have a WPF application where a line shape is only displayed when the application window is resized, as shown here:

The red line is drawn on-the-fly, it is not defined in XAML. It displays fine.

The blue line is defined in XAML, but its dimensions are changed within the OnRender() call. If its dimensions are not changed, or if only some of its dimensions are changed, the blue line is displayed on startup. But when all the dimensions of the blue line are changed, it is not displayed on startup. It is only displayed on application resize.

Here's the XAML code:

<Window x:Class="canvas_line.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:canvas_line" 
        Title="MainWindow" Height="284" Width="228">
    <Canvas Name="canvas">
        <local:show_line />
        <Line Name="my_line" Stroke="Blue" 
            X1="50" Y1="40" X2="50" Y2="80" StrokeThickness="4" />
    </Canvas>
</Window>

And the C# code-behind file:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Linq;

namespace canvas_line
{
    public partial class show_line: FrameworkElement
    {
        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);              // Good practice.

            // Draw a brand-new red line defined here only 
            // (not defined in XAML).

            Pen dp = new Pen(Brushes.Red, 4);
            dc.DrawLine(dp, new Point(100, 150), new Point(100, 200));

            // Now modify coordinates of the blue line defined in XAML.

            Canvas cp = (Canvas)this.Parent;
            var my_line = cp.Children.OfType<Line>().FirstOrDefault();
            my_line.X1 = 100;
            my_line.Y1 = 20;
            my_line.X2 = 100;
            my_line.Y2 = 50;

            // Problem: The blue line is not displayed unless
            // the application window is resized.
        }
    }
}

The zip file for the entire project is here (there is very little code in the project, I have pruned it to the absolute minimum necessary to demo the problem):

https://anonfiles.com/file/18c6edce296927b43ed0b0d595574a80

I have tried all sorts of combinations of calls to UpdateLayout() and InvalidateVisual(), to no effect. Why is this happening, and is there a workaround? My ultimate goal is to be able to animate the blue line so as to have it blink.

I am on Windows 7, Visual Studio 10, .NET 4.0 Client Profile.

回答1:

if you put it like this it will draw properly

 <Canvas Name="canvas">
    <Line Name="my_line" Stroke="Blue" X1="50" Y1="40" X2="50" Y2="80" StrokeThickness="4" />
    <local:show_line />
 </Canvas>