设置画布背景颜色

huangapple go评论93阅读模式
英文:

Setting Background color on Canvas

问题

我正在尝试创建一个在WPF中显示纯白色图像的全屏窗口。窗口包含一个带有黑色边框的画布,该边框指示距离图像边缘25%长度/宽度的区域。分辨率可能会变化,所以我需要在运行时创建它。

问题是,无论我尝试什么,最终都得到一个完全黑色的窗口。

要在代码后台中重现此问题:在VisualStudio中创建新的WPF应用程序,并添加一个按钮:

<Button Click="Button_Click"/>

然后在代码后台中添加以下代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    double screenWidth = SystemParameters.FullPrimaryScreenWidth; //获取显示器宽度
    double screenHeight = SystemParameters.FullPrimaryScreenHeight; //获取显示器高度

    System.Windows.Window window = new System.Windows.Window(); //创建新窗口
    window.WindowStyle = WindowStyle.None; //无样式
    window.WindowState = WindowState.Maximized; //全屏

    window.Background = Brushes.White;//白色背景!
    window.MouseMove += new System.Windows.Input.MouseEventHandler(window_MouseMove); //监视鼠标位置的事件

    int frameWidth = (int)(screenWidth * 0.25);
    int frameHeight = (int)(screenHeight * 0.25);
    int frameX = (int)((screenWidth - frameWidth) / 2);
    int frameY = (int)((screenHeight - frameHeight) / 2);
    ///生成距离边缘25%的边框


    Canvas canvas = new Canvas();
    canvas.Width = screenWidth;
    canvas.Height = screenHeight;
    canvas.Background = Brushes.White; //画布白色背景!
    canvas.Children.Add(new System.Windows.Shapes.Rectangle
    {
        Width = frameWidth,
        Height = frameHeight,
        Stroke = Brushes.Black,
        StrokeThickness = 3,
        Margin = new Thickness(frameX, frameY, 0, 0)
    });
    //创建具有正确分辨率的画布并将颜色设置为白色,然后添加一个黑色边框


    RenderTargetBitmap bitmap = new RenderTargetBitmap((int)screenWidth, (int)screenHeight, 96, 96, PixelFormats.Pbgra32);

    bitmap.Render(canvas); //将位图设置为渲染画布

    ImageBrush brush = new ImageBrush(bitmap);

    brush.TileMode = TileMode.None;//如果刷子具有黑边框并且平铺得太小,边框可能会创建黑色图像

    window.Background = brush; //将窗口背景再次设置为白色

    window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); //强制窗口执行布局和测量过程

    window.ShowDialog(); //打开一个白色窗口,其中包含一个白色画布:一切都是黑色
}
private void window_MouseMove(object sender, MouseEventArgs e)
{
    System.Windows.Point mousePosition = e.GetPosition((IInputElement)sender);
    Console.WriteLine($"MousePosition = {mousePosition}");
}

这段代码应该显示一个白色图像,但一切都是黑色。

我尝试了通过设置刷子的TileMode属性为None来强制正确显示画布。我还尝试使用DrawingVisual代替Canvas

英文:

I am trying to make a Fullscreen window that displays a solid white image in wpf.
The window contains a Canvas with a Black frame that indicates the area that is 25% of the imagesizes length/width from the edge. The resolution may vary, so I need to create it at runtime.

The issue is that no matter what I try to do, I end up with a colmpletely black window.

To reproduce the issue in code behind: Make new wpf application in VisualStudio, and add a button:
&lt;Button Click=&quot;Button_Click&quot;/&gt;
to the Window.

then in code behind:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            double screenWidth = SystemParameters.FullPrimaryScreenWidth; //Get Monitor width
            double screenHeight = SystemParameters.FullPrimaryScreenHeight; //Get Monitor height

            System.Windows.Window window = new System.Windows.Window(); //new window
            window.WindowStyle = WindowStyle.None; //No style
            window.WindowState = WindowState.Maximized; //Fullscreen

            window.Background = Brushes.White;//White Background!
            window.MouseMove += new System.Windows.Input.MouseEventHandler(window_MouseMove); //Event checking mousePos

            int frameWidth = (int)(screenWidth * 0.25);
            int frameHeight = (int)(screenHeight * 0.25);
            int frameX = (int)((screenWidth - frameWidth) / 2);
            int frameY = (int)((screenHeight - frameHeight) / 2);
            ///Generate a frame 25% in from the edges


            Canvas canvas = new Canvas();
            canvas.Width = screenWidth;
            canvas.Height = screenHeight;
            canvas.Background = Brushes.White; //Canvas White Background!
            canvas.Children.Add(new System.Windows.Shapes.Rectangle
            {
                Width = frameWidth,
                Height = frameHeight,
                Stroke = Brushes.Black,
                StrokeThickness = 3,
                Margin = new Thickness(frameX, frameY, 0, 0)
            });
            //Create the Canvas with the correct resolution and set the color to white, then add a black frame


            RenderTargetBitmap bitmap = new RenderTargetBitmap((int)screenWidth, (int)screenHeight, 96, 96, PixelFormats.Pbgra32);
            
            bitmap.Render(canvas); //Set bitmap to render the canvas

            ImageBrush brush = new ImageBrush(bitmap);
            
            brush.TileMode = TileMode.None;//If brush has black border and is tiled to small, the borders could create a black image

            window.Background = brush; //Set the window background to white again

            window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); //Force the window to perform layout and measure pass.

            window.ShowDialog(); // Open the White window with a White Canvas: Everything is black
        }
        private void window_MouseMove(object sender, MouseEventArgs e)
        {
            System.Windows.Point mousePosition = e.GetPosition((IInputElement)sender);
            Console.WriteLine($&quot;MousePosition = {mousePosition}&quot;);
        }

This code should have showed me a white image, but everthing is black

I have tried to force proper display of canvas by setting brush TileMode.None.
I have also tried using DrawingVisual instead of Canvas

答案1

得分: 1

我不确定你的窗口是如何创建的,但你可以尝试在窗口内创建一个网格。

<Window>
    <Grid x:Name="MainGrid">
    
    </Grid>
</Window>

然后在你的 Button_Click 代码中,你可以尝试:

MainGrid.Children.Add(canvas);
英文:

I am not sure how your Window is created but you can try creating a grid inside your window.

&lt;Window&gt;
&lt;Grid x:Name=&quot;MainGrid&quot;&gt;

&lt;/Grid&gt;
&lt;/Window&gt;

and then on your Button_Click code you can try

MainGrid.Children.Add(canvas);

答案2

得分: 0

这是我认为正在发生的事情,但我不是一个WPF专家,所以要持怀疑态度。

当您将画布渲染为位图时,不会呈现背景。因此,位图的背景应该是透明黑色。当您将这个位图设置为窗口背景的渲染画笔时,渲染器无法输出透明,因为窗口下面没有什么东西。所以它要么忽略位图的透明度,要么将位图颜色与黑色混合。无论哪种情况,结果都将是黑色。

最简单的解决方法是跳过位图步骤,直接将画布添加到窗口中,就像Izanagis的答案中所示。

如果出于某种原因不希望这样做,一种解决方法可能是将图像添加到窗口并将位图设置为图像源。或者可能只需添加一个网格并将网格的背景画刷设置为窗口的背景,而不是直接设置窗口的背景。但只有在您有特殊原因要将位图用作中间值时才这样做。如果是这种情况,我可能会考虑使用Graphics.FromImage,因为我发现这种方法在绘制图形时更容易使用。

英文:

This is what I expect is happening, but I'm not a wpf expert, so take it with a grain of salt.

When you render the canvas to a bitmap no background will rendered. So the background of the bitmap should be transparent black. When you set this bitmap as the rendering brush of the window background the renderer cannot cannot output transparent, since there is nothing "beneath" the window. So it either ignores the transparency of the bitmap, or blends the bitmap color with black. In either case the result will be black.

The simplest solution is to just skip the bitmap step and add the canvas to the window directly. As shown in Izanagis answer.

If this is for some reason not desired a workaround might be to add an image to the window and set the bitmap as the image source. Or possibly just add a grid and set the background brush of the grid instead of the window. But would only do this if you have some special reason to use a bitmap as an intermediate value. If this is the case I would probably consider using Graphics.FromImage instead, since I find that method easier when drawing graphics.

huangapple
  • 本文由 发表于 2023年3月3日 18:32:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75625931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定