locked
Blur Behind option for WPF Controls within the application RRS feed

  • Question

  • Hi,

    I am trying to create a UI in WPF 4.6 similar to the one shown here
    http://i1-news.softpedia-static.com/images/news2/Windows-10-Looks-Stunning-in-New-Design-Concept-468398-5.jpg


    I was able to add the blur behind option to the Window based on the excellent tip from the blog article by Rafael Rivera Adding the "Aero Glass" blur to your Windows 10 apps.

     
    However, I have another question related to this. This solution applies the blur effect to the entire window. How can I modify your solution so that a child control within the window has the same blur effect over the window content. For e.g. a blurred and translucent title bar at the top of a Listbox which shows the topmost content below as blurred when the user scrolls the listbox contents. 
     
    Also, can I extend this solution to make the context menus also translucent.

    As per the blog article, the SetWindowCompositionAttribute is not properly documented. Could you please provide some links or info on how to use the powerful DWM to obtain such effects within the application?


    Thanks

    Tuesday, September 15, 2015 5:27 PM

All replies

  • Hi,

    "For e.g. a blurred and translucent title bar at the top of a Listbox which shows the topmost content below as blurred when the user scrolls the listbox contents. "

    You could use the hRgnBlur of the DWM_BLURBEHIND, read these links would be helpful.

    http://stackoverflow.com/questions/27787966/winapi-dwmapi-blur-behind-window-with-irregular-shape

    https://coldjackle.wordpress.com/2012/07/17/c-aero-glass/

    Wednesday, September 16, 2015 8:36 AM
  • Hi,

    Thanks for the reply.

    I tried the links you provided. However, in Windows 10 when I call the DwmEnableBlurBehindWindow() API it does not create a blurred background for the Region provided. Instead that region becomes black in color.

    Also this link says that we should avoid using DwmEnableBlurBehindWindow and DwmExtendFrameIntoClientArea APIs and use SetWindowCompositionAttribute instead.

    The problem with SetWindowCompositionAttribute seems to be that it always blurs a rectangular region behind the window.

    Even if I use SetWindowRgn API to set (say an elliptical) region for the window, still the rectangular area encapsulating the ellipse is blurred.

    Here is my code

    var windowHelper = new WindowInteropHelper(window);
    var hwnd = windowHelper.Handle;
    
    var hwndSource = HwndSource.FromHwnd(hwnd);
    var sizeFactor = hwndSource.CompositionTarget.TransformToDevice.Transform(new Vector(1.0, 1.0));
    
    window.Background = System.Windows.Media.Brushes.Transparent;
    hwndSource.CompositionTarget.BackgroundColor = Colors.Transparent;
    
    using (var path = new GraphicsPath())
    {
    	path.AddEllipse(0, 0, (int)(window.ActualWidth * sizeFactor.X), (int)(window.ActualHeight * sizeFactor.Y));
    
    	var newRgn = new Region(path);
    	using (var graphics = Graphics.FromHwnd(hwnd))
    	{
    		var nRgn = newRgn.GetHrgn(graphics);
    		
    		// Set the window region to be elliptical
    		Interop.SetWindowRgn(hwnd, nRgn, true);
    
    		var accent = new Interop.AccentPolicy();
    		accent.AccentState = Interop.AccentState.ACCENT_ENABLE_BLURBEHIND;
    		accent.AccentFlags = GetAccentFlagsForTaskbarPosition();
    
    
    		var accentStructSize = Marshal.SizeOf(accent);
    
    
    		var accentPtr = Marshal.AllocHGlobal(accentStructSize);
    		Marshal.StructureToPtr(accent, accentPtr, false);
    
    
    		var data = new Interop.WindowCompositionAttribData();
    		data.Attribute = Interop.WindowCompositionAttribute.WCA_ACCENT_POLICY;
    		data.SizeOfData = accentStructSize;
    		data.Data = accentPtr;
    
    		Interop.SetWindowCompositionAttribute(hwnd, ref data);
    
    		Marshal.FreeHGlobal(accentPtr);
    
    		newRgn.ReleaseHrgn(nRgn);
    	}
    }
    

    Wednesday, September 16, 2015 10:59 PM
  • Unfortunately, I am still not able to find a solution to this problem.

    Please help me.

    Wednesday, November 11, 2015 11:17 PM
  • If these are wpf controls you intend blurring then you can use the blur effect.

    https://msdn.microsoft.com/library/ms742795(v=vs.90).aspx

    And you can apply that with a trigger or datatrigger:

        <Button  Width="200">
          Click to Blur ME!
          <Button.BitmapEffect>
    
            <!-- This BitmapEffect is targeted by the animation. -->
            <BlurBitmapEffect x:Name="myBlurBitmapEffect"  Radius="0" />
    
          </Button.BitmapEffect>
          <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
              <BeginStoryboard>
                <Storyboard>
    
                  <!-- Blur the Button and then animate back to normal. -->
                  <DoubleAnimation
                   Storyboard.TargetName="myBlurBitmapEffect"
                   Storyboard.TargetProperty="Radius"
                   From="0" To="40" Duration="0:0:0.3"
                   AutoReverse="True" />
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </Button.Triggers>
        </Button>

    I should think you could even animate or bind the blur radius so the speed they scroll at increases the blur.

    That link you posted looks to be setting opacity though.

    If you set opacity on a panel or control to lower than 1 then you'll be able to see whatever's behind it like that "Pictures Library" header thing and the footers on each image - "Wall 16" for example.


    Hope that helps.

    Technet articles: WPF: MVVM Step 1; All my Technet Articles

    Thursday, November 12, 2015 10:15 AM