简体   繁体   English

令人困惑的WPF抽奖行为

[英]Confusing WPF draw behavior

I'm currently trying to persist a canvas to a bitmap, and I've run into some very peculiar behavior. 我目前正在尝试将画布保留到位图,并且遇到了一些非常特殊的行为。 The source code for the 3 following cases appears at the end of the post. 以下三种情况的源代码显示在帖子的末尾。

Case 1: A red rectangle appears in the output file (test.png), as expected. 情况1:预期会在输出文件(test.png)中出现一个红色矩形。

Case 2: No red rectangle appears in the output file. 情况2:在输出文件中没有红色矩形出现。

Case 3: No red rectangle appears in the output file. 情况3:在输出文件中没有红色矩形出现。

It seems that adding the rectangle to the canvas (even though that canvas is never used to render the rectangle to disk) is necessary. 似乎需要将矩形添加到画布上(即使从未使用该画布将矩形渲染到磁盘上)。 It also seems that the button click must initiate the drawing - that it can't occur in the Window constructor. 似乎单击按钮也必须启动绘图-它不能在Window构造函数中发生。 Neither of these makes sense to me, and I assume I'm misunderstanding something. 这些都不对我有意义,我认为我误会了一些东西。

Also, I apologize in advance for the bad code formatting. 另外,对于错误的代码格式,我也表示歉意。 I wrestled with it for 20 minutes, but now I'm giving up. 我与它搏斗了20分钟,但现在我放弃了。

Thanks in advance, 提前致谢,

-- Breck Fresen -布雷克·弗雷森(Breck Fresen)

The XAML used for all 3 cases: XAML用于所有3种情况:

<Window x:Class="ScanOutlineCreator.Window1"   
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    Title="Window1" Height="250" Width="250">  
        <Grid>  
            <Grid.RowDefinitions>  
                <RowDefinition Height="20" />  
                <RowDefinition />  
            </Grid.RowDefinitions>  
            <Button x:Name="btnGo" Grid.Row="0">  
                <TextBlock Text="Go" />  
            </Button>  
            <Canvas Grid.Row="1" x:Name="canvas" Width="200" Height="500"></Canvas>  
        </Grid>  
</Window>

Case 1: 情况1:

using System.IO;  
using System.Windows;  
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using System.Windows.Shapes;  
using Common.Drawing;  
namespace ScanOutlineCreator  
{  
        public partial class Window1  
        {  
                static Rectangle r = new Rectangle { Width = 100, Height = 100, Fill = Brushes.Red };  
                public Window1()  
                {  
                        InitializeComponent();  
                        btnGo.Click += new RoutedEventHandler(btnGo_Click);  
                        canvas.Children.Add(r);  
                }  

                static void btnGo_Click(object sender, RoutedEventArgs e)  
                {  
                        using (Stream stm = File.Create("test.png"))  
                        {  
                                RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);  
                                rtb.Render(r);  
                                Util.RenderTargetBitmapToStream(rtb, stm);  
                        }  
                }  
        }  
}  

Case 2: 情况2:

using System.IO;  
using System.Windows;   
using System.Windows.Media;   
using System.Windows.Media.Imaging;   
using System.Windows.Shapes;   
using Common.Drawing;

namespace ScanOutlineCreator     
{     
    public partial class Window1   
    {   
        static Rectangle r = new Rectangle { Width = 100, Height = 100, Fill = Brushes.Red };  
        public Window1()   
        {   
            InitializeComponent();   
            btnGo.Click += new RoutedEventHandler(btnGo_Click);   
        }  

        static void btnGo_Click(object sender, RoutedEventArgs e)   
        {   
            using (Stream stm = File.Create("test.png"))   
            {   
                RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);   
                rtb.Render(r);   
                Util.RenderTargetBitmapToStream(rtb, stm);   
            }   
        }   
    }   
}   

Case 3: 情况3:

using System.IO;   
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using System.Windows.Shapes;  
using Common.Drawing;  
namespace ScanOutlineCreator  
{  
    public partial class Window1  
    {  
        static Rectangle r = new Rectangle { Width = 100, Height = 100, Fill = Brushes.Red };  
        public Window1()
        {  
            InitializeComponent();  
            canvas.Children.Add(r);  
            using (Stream stm = File.Create("test.png"))  
            {  
                RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96, 96, PixelFormats.Pbgra32);  
                rtb.Render(r);  
                Util.RenderTargetBitmapToStream(rtb, stm);  
            }  
        }  
    } 
}

This is almost certainly to do with layout. 几乎可以肯定这与布局有关。 If so its been covered many times before. 如果是这样,它已经被覆盖了很多次。

After you add the children you have to make sure Layout gets performed before you render, so things are actually in the visual tree in the right location etc. 添加子项后,必须确保在渲染之前执行了Layout,所以实际上它们在视觉树中的正确位置等。

You probably need to call some combination of Measure/Arrange before rendering. 在渲染之前,您可能需要调用Measure / Arrange的某种组合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM