Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

WPF VisualBrush Canvas as Mask not positioned correctly

$
0
0

I have got an issue with using a Canvas as a OpacityMask. As you can see in the image below. I have got some Rectangles which should have a blurred background, however the blur is offset to the Rectangles, you should be able to make it out.

As you can see it looks like the OpacityMask is offset and not aligned correctly. However is I append this canvas to a new window the rectangles are in the correct position!

(In the black and white photo above - the canvas - the top left rectangle is a different size, that is just because I took the screenshot after I made it a bit wider so ignore that)

This is the code which generates the rectangles and canvas:

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            List<Rectangle> MaskBlocks = new List<Rectangle>();
            Canvas c = new Canvas();
            c.Width = this.ActualWidth; c.Height = this.ActualHeight;

            foreach (DockPanel gr in FindVisualChildren<DockPanel>(Container))
                if (gr.Tag != null && gr.Tag.ToString() == "Blur")
                {
                    System.Windows.Point tmp = gr.TransformToAncestor(this).Transform(new System.Windows.Point(0, 0));

                    MaskBlocks.Add(new Rectangle(new System.Drawing.Point((int)tmp.X,(int)tmp.Y),
                        new System.Drawing.Size((int)gr.ActualWidth, (int)gr.ActualHeight)));
                }

            foreach(Rectangle x in MaskBlocks)
            {
                System.Windows.Shapes.Rectangle tmp;
                tmp = new System.Windows.Shapes.Rectangle();
                tmp.Stroke = new SolidColorBrush(Colors.Black);
                tmp.Fill = new SolidColorBrush(Colors.Black);
                tmp.Width = x.Width;
                tmp.Height = x.Height;
                Canvas.SetLeft(tmp, x.X);
                Canvas.SetTop(tmp, x.Y);
                c.Children.Add(tmp);
            }
            BGImage.OpacityMask = new VisualBrush(c);
        }

And the XAML if you need:

<Window x:Class="BlurEffectTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BlurEffectTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"><Window.Resources><Style TargetType="DockPanel"><Setter Property="Background" Value="#FF1A1A1A" /><Setter Property="Opacity" Value="0.7" /></Style><Style TargetType="Border"><Setter Property="BorderBrush" Value="White" /><Setter Property="BorderThickness" Value="1" /><Setter Property="VerticalAlignment" Value="Stretch" /></Style></Window.Resources><Grid Name="Container"><Grid.Background><ImageBrush Stretch="Fill" ImageSource="bg.jpg" /></Grid.Background><Image Source="bg.jpg" Stretch="Fill" Name="BGImage"><Image.Effect><BlurEffect Radius="15" /></Image.Effect></Image><DockPanel Margin="10,10,378,175" Tag="Blur"><Border /></DockPanel><DockPanel Margin="236,10,26,161" Tag="Blur"><Border><StackPanel><Button Click="Button_Click" Content="Start" /><StackPanel x:Name="stackPanel" VerticalAlignment="Stretch" Height="127" /></StackPanel></Border></DockPanel><DockPanel Margin="10,244,261,22" Tag="Blur"><Border /></DockPanel><DockPanel Margin="10,186,321,101" Tag="Blur"><Border /></DockPanel></Grid></Window>

Edit:

Some better images, if I remove the background image, and the blur, and run the code I get the following:

In the image below I have added the code `this.Content = c` which replaces the Windows content with the canvas, which displays this, which is the same way the mask should appear!


3D Modeller



Viewing all articles
Browse latest Browse all 18858

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>