令人困惑的WPF绘制行为

时间:2010-02-05 07:47:26

标签: c# wpf drawing

我目前正在尝试将画布持久化到位图,并且我遇到了一些非常特殊的行为。以下3个案例的源代码显示在帖子的末尾。

案例1:输出文件(test.png)中出现一个红色矩形,如预期的那样。

案例2:输出文件中没有红色矩形。

案例3:输出文件中不显示红色矩形。

似乎将矩形添加到画布(即使从不使用该画布将矩形渲染到磁盘)也是必要的。按钮单击似乎也必须启动绘图 - 它不能在Window构造函数中出现。这些都不合理,我认为我误解了一些东西。

另外,我为错误的代码格式提前道歉。我和它搏斗了20分钟,但现在我放弃了。

提前致谢,

- Breck Fresen

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>

案例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);  
                        }  
                }  
        }  
}  

案例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);   
            }   
        }   
    }   
}   

案例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);  
            }  
        }  
    } 
}

1 个答案:

答案 0 :(得分:0)

这几乎肯定与布局有关。如果是这样,它之前已被多次覆盖。

添加子项后,您必须确保在渲染之前执行Layout,因此事物实际上位于正确位置的可视树中等。

你可能需要在渲染之前调用一些Measure / Arrange的组合。