2016-11-18 7 views
9

Areo Szkło Effect i windowStyle ustawiona na none i AllowTransparency powoduje wdowa rozmiaru aby nie działać poprawnieAreo Szkło Effect i windowStyle ustawiona na none powoduje wdowa rozmiaru nie funkcjonować prawidłowo

Po dodaniu motywu Areo Szkło do mojego okna i ustawienie WindowState to None, okno nie zmienia się poprawnie. Mogę iść tak duży, jak chcę, ale gdy zmniejszam rozmiar, efekt szkła pozostaje na tej samej szerokości i wysokości.

Na przykład klikam Maksymalizuj. Okno Rozwija się na cały ekran. Ale po przywróceniu moje okno przywraca z powrotem, ale nie efekt szkła.

Wszystko, czego naprawdę chcę, to efekt rozmycia. Nie dbam o szkło, ale wydaje mi się, że to jedyny sposób, w jaki mogę uzyskać przezroczyste rozmycie.

Jak mogę to naprawić? To doprowadza mnie do szału! Proszę pomóż.

AnyOne ???

XAML

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" WindowStyle="None" ResizeMode="CanResizeWithGrip" Background="Transparent"> 
    <Border BorderThickness="1" Margin="0,35,0,0" BorderBrush="Orange"> 
    <Grid Background="#0CFFA500"> 

      <DockPanel VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="35" Background="#4effffff"> 
      <DockPanel.Resources> 
       <Style x:Key="WindowIconStyle" TargetType="{x:Type Button}"> 
        <Setter Property="FontSize" Value="16" /> 
        <Setter Property="Foreground" Value="#444" /> 
        <Setter Property="Height" Value="30"></Setter> 
        <Setter Property="Width" Value="30"></Setter> 
        <Setter Property="FontFamily" Value="Webdings"></Setter> 
        <Setter Property="Background" Value="#ff0000"></Setter> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type Button}"> 
           <Border BorderBrush="Transparent" BorderThickness="0.5,0,0.5,0"> 
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> 
           </Border> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
        <Style.Triggers> 
         <Trigger Property="IsMouseOver" Value="True"> 
          <Setter Property="Background" Value="#77abff" /> 
          <Setter Property="Foreground" Value="#000000" /> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type Button}"> 
             <Border BorderBrush="Black" BorderThickness="1,0,1,0"> 
              <Border.Background> 
               <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0"> 
                <GradientStop Color="Black" Offset="1"/> 
                <GradientStop Color="White" Offset="0.952"/> 
                <GradientStop Color="Black" Offset="0"/> 
                <GradientStop Color="#FFF7F7F7" Offset="0.044"/> 
               </LinearGradientBrush> 
              </Border.Background> 
              <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> 
             </Border> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Trigger> 
         <Trigger Property="IsPressed" Value="True"> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type Button}"> 
             <Border BorderBrush="#444" BorderThickness="1,0,1,0"> 
              <Border.Background> 
               <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0"> 
                <GradientStop Color="#444" Offset="1"/> 
                <GradientStop Color="#ffececec" Offset="0.952"/> 
                <GradientStop Color="#444" Offset="0"/> 
                <GradientStop Color="#ffececec" Offset="0.044"/> 
               </LinearGradientBrush> 
              </Border.Background> 
              <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> 
             </Border> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Trigger> 
        </Style.Triggers> 
       </Style> 
      </DockPanel.Resources> 
      <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerClose" Style="{StaticResource WindowIconStyle}" Content="r" /> 
      <Button x:Name="btnMaximize" DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMaximize" Style="{StaticResource WindowIconStyle}" Content="c" /> 
      <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMinimize" Style="{StaticResource WindowIconStyle}" Content="0" /> 
      <StatusBar Background="Transparent" MouseDoubleClick="TriggerMaximize" MouseMove="TriggerMoveWindow" > 
       <TextBlock DockPanel.Dock="Left" x:Name="txtTitle" Text="Title" FontSize="16" Padding="10,0,0,0"/> 
      </StatusBar> 
     </DockPanel> 
      <Border BorderThickness="0,1,0,0" Margin="0,35,0,0" BorderBrush="#f7000000"> 

     </Border> 
    </Grid> 
    </Border> 
</Window> 

C#

using System; 
using System.Runtime.InteropServices; 
using System.Windows; 
using System.Windows.Input; 
using System.Windows.Interop; 


namespace WpfApplication2 { 

    public partial class MainWindow : Window { 

     #region Constants 

     private System.Windows.Window me { get; set; } 
     private const int WM_DWMCOMPOSITIONCHANGED = 0x031E; 
     private const int DWM_BB_ENABLE = 0x1; 

     #endregion //Constants 

     #region Structures 
     [StructLayout(LayoutKind.Sequential)] 
     private struct DWM_BLURBEHIND { 
      public int dwFlags; 
      public bool fEnable; 
      public IntPtr hRgnBlur; 
      public bool fTransitionOnMaximized; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private struct MARGINS { 
      public int cxLeftWidth; 
      public int cxRightWidth; 
      public int cyTopHeight; 
      public int cyBottomHeight; 
     } 
     #endregion //Structures 

     #region APIs 

     [DllImport("dwmapi.dll", PreserveSig = false)] 
     private static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind); 
     [DllImport("dwmapi.dll")] 
     private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins); 
     [DllImport("dwmapi.dll", PreserveSig = false)] 
     private static extern bool DwmIsCompositionEnabled(); 

     #endregion //APIs 

     public MainWindow() { 
      SourceInitialized += OnSourceInitialized; 
      InitializeComponent(); 
     } 

     private void OnSourceInitialized(object sender, EventArgs eventArgs) { 
      me = (Window)sender; 
      if (Environment.OSVersion.Version.Major >= 6) { 
       var hwnd = new WindowInteropHelper(me).Handle; 
       var hs = HwndSource.FromHwnd(hwnd); 
       hs.CompositionTarget.BackgroundColor = System.Windows.Media.Colors.Transparent; 

       hs.AddHook(new HwndSourceHook(this.WndProc)); 
       this.InitializeGlass(hwnd); 
      } 

     } 

     public System.Windows.Media.Color GetAreoColor() { 
      int icolor = (int)Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", null); 
      var c = System.Drawing.Color.FromArgb(icolor); 
      return System.Windows.Media.Color.FromArgb(c.A, c.R, c.G, c.B); 
     } 


     private static String ConverterToHex(System.Drawing.Color c) { 
      return String.Format("#{0}{1}{2}", c.R.ToString("X2"), c.G.ToString("X2"), c.B.ToString("X2")); 
     } 

     #region Methods 

     #region InitializeGlass 
     public void InitializeGlass(IntPtr hwnd) { 
      if (!DwmIsCompositionEnabled()) 
       return; 

      // fill the background with glass 
      var margins = new MARGINS(); 
      margins.cxLeftWidth = margins.cxRightWidth = margins.cyBottomHeight = margins.cyTopHeight = -1; 
      DwmExtendFrameIntoClientArea(hwnd, ref margins); 

      // initialize blur for the window 
      DWM_BLURBEHIND bbh = new DWM_BLURBEHIND(); 
      bbh.fEnable = true; 
      // bbh.fTransitionOnMaximized = true; 

      bbh.dwFlags = DWM_BB_ENABLE; 
      DwmEnableBlurBehindWindow(hwnd, ref bbh); 
     } 
     #endregion //InitializeGlass 

     #region WndProc 
     private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { 
      if (msg == WM_DWMCOMPOSITIONCHANGED) { 
       this.InitializeGlass(hwnd); 
       handled = false; 
      } 

      return IntPtr.Zero; 
     } 
     #endregion //WndProc 

     #endregion //Methods 


     private void TriggerMoveWindow(object sender, MouseEventArgs e) { 
      if (e.LeftButton == MouseButtonState.Pressed) { 
       if (WindowState == System.Windows.WindowState.Maximized) { 
        WindowState = System.Windows.WindowState.Normal; 

        double pct = PointToScreen(e.GetPosition(this)).X/System.Windows.SystemParameters.PrimaryScreenWidth; 
        Top = 0; 
        Left = e.GetPosition(this).X - (pct * Width); 
       } 

       Application.Current.MainWindow.DragMove(); 
      } 
     } 

     private void TriggerMaximize(object sender, EventArgs e) { 
      if (WindowState == System.Windows.WindowState.Maximized) { 
       WindowState = System.Windows.WindowState.Normal; 
       btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Webdings"); 
       btnMaximize.Content = "c"; 
      } else if (WindowState == System.Windows.WindowState.Normal) { 
       WindowState = System.Windows.WindowState.Maximized; 
       btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Wingdings"); 
       btnMaximize.Content = "r"; 
       InvalidateVisual(); 
      } 
     } 

     private void TriggerClose(object sender, RoutedEventArgs e) { 
       Close(); 
     } 

     private void TriggerMinimize(object sender, RoutedEventArgs e) { 
      WindowState = System.Windows.WindowState.Minimized; 
     } 
    } 
} 

enter image description here

+0

Czy mogę zadać pytanie Źle? Cały kod jest tutaj, aby zreplikować problem. Daje 50 nagrodę temu, który może poprawnie odpowiedzieć na problem. – Mike

+0

Witam, rzuciłem okiem na to, ale nie jestem pewien, co jest nie tak. Chciałem tylko wspomnieć, że używając twojego przykładu, rozmycie w ogóle nie działa - zamiast tego otrzymuję zwykły, biały blok, w którym powinna być przezroczystość (przy użyciu Windows 8.1) –

+0

s_mg ten przykład działa tylko z Oknem 7. Nie ma rozmycie w systemie Windows 8, które mogłem znaleźć. Microsoft go wyłączył. Przywróciłem go z Windows 10, ale działa znacznie łatwiej niż mój kod powyżej.Ostateczne rozwiązanie sprawdza wersję systemu Windows podczas inicjowania, a następnie przechodzi z tego miejsca. [blur-behind-transparent-wpf-window] (http://stackoverflow.com/questions/31778017/blur-behind-transparent-wpf-window) – Mike

Odpowiedz

3

Wydaje się, że AllowsTransparency == True jest źródłem tego zachowania. Dlatego możesz go usunąć. Jednakże, należy ustawić przezroczystość tła Brush wynosi zero:

<Window.Background> 
    <SolidColorBrush Opacity="0" Color="Transparent"/> 
</Window.Background> 

to wraz z ustawieniem CompositionTarget.BackgroundColor być przejrzyste, a także za pomocą DwmEnableBlurBehindWindow funkcji sprawi, podobny wynik do ustawiania AllowsTransparency == True.

Jednak dzięki tym modyfikacjom wygląd okna nie jest zbyt przyjemny ze względu na jego obramowanie. Obramowanie zniknie, jeśli ustawisz ResizeMode=="NoResize". Jednak w takim przypadku powinieneś zaimplementować zmianę rozmiaru siebie. Na szczęście jest to łatwe dzięki dodaniu kciuka i obsłudze zdarzenia DragDelta. Oto pełny kod:

Xaml

<Window x:Class="Test1.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:Test1" 
    mc:Ignorable="d" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    Title="MainWindow" Name="window" 
    Height="350" Width="525" WindowStyle="None" ResizeMode="NoResize" > 
<Window.Background> 
    <SolidColorBrush Opacity="0" Color="Transparent"/> 
</Window.Background> 

<Grid> 
    <Thumb DockPanel.Dock="Bottom" DragDelta="Thumb_DragDelta" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="8" Height="8" Cursor="SizeNWSE" Background="Red" Panel.ZIndex="4"/> 
    <Border BorderThickness="1" BorderBrush="Orange" Margin="0,0,0,0"> 
     <Grid Background="#0CFFA500"> 
      <DockPanel VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="35" Background="#4effffff"> 
       <DockPanel.Resources> 
        <Style x:Key="WindowIconStyle" TargetType="{x:Type Button}"> 
         <Setter Property="FontSize" Value="16" /> 
         <Setter Property="Foreground" Value="#444" /> 
         <Setter Property="Height" Value="30"></Setter> 
         <Setter Property="Width" Value="30"></Setter> 
         <Setter Property="FontFamily" Value="Webdings"></Setter> 
         <Setter Property="Background" Value="#ff0000"></Setter> 
         <Setter Property="Template"> 
          <Setter.Value> 
           <ControlTemplate TargetType="{x:Type Button}"> 
            <Border BorderBrush="Transparent" BorderThickness="0.5,0,0.5,0"> 
             <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> 
            </Border> 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
         <Style.Triggers> 
          <Trigger Property="IsMouseOver" Value="True"> 
           <Setter Property="Background" Value="#77abff" /> 
           <Setter Property="Foreground" Value="#000000" /> 
           <Setter Property="Template"> 
            <Setter.Value> 
             <ControlTemplate TargetType="{x:Type Button}"> 
              <Border BorderBrush="Black" BorderThickness="1,0,1,0"> 
               <Border.Background> 
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0"> 
                 <GradientStop Color="Black" Offset="1"/> 
                 <GradientStop Color="White" Offset="0.952"/> 
                 <GradientStop Color="Black" Offset="0"/> 
                 <GradientStop Color="#FFF7F7F7" Offset="0.044"/> 
                </LinearGradientBrush> 
               </Border.Background> 
               <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> 
              </Border> 
             </ControlTemplate> 
            </Setter.Value> 
           </Setter> 
          </Trigger> 
          <Trigger Property="IsPressed" Value="True"> 
           <Setter Property="Template"> 
            <Setter.Value> 
             <ControlTemplate TargetType="{x:Type Button}"> 
              <Border BorderBrush="#444" BorderThickness="1,0,1,0"> 
               <Border.Background> 
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0"> 
                 <GradientStop Color="#444" Offset="1"/> 
                 <GradientStop Color="#ffececec" Offset="0.952"/> 
                 <GradientStop Color="#444" Offset="0"/> 
                 <GradientStop Color="#ffececec" Offset="0.044"/> 
                </LinearGradientBrush> 
               </Border.Background> 
               <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> 
              </Border> 
             </ControlTemplate> 
            </Setter.Value> 
           </Setter> 
          </Trigger> 
         </Style.Triggers> 
        </Style> 
       </DockPanel.Resources> 
       <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerClose" Style="{StaticResource WindowIconStyle}" Content="r" /> 
       <Button x:Name="btnMaximize" DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMaximize" Style="{StaticResource WindowIconStyle}" Content="c" /> 
       <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMinimize" Style="{StaticResource WindowIconStyle}" Content="0" /> 
       <StatusBar Background="Transparent" MouseDoubleClick="TriggerMaximize" MouseMove="TriggerMoveWindow" > 
        <TextBlock DockPanel.Dock="Left" x:Name="txtTitle" Text="Title" FontSize="16" Padding="10,0,0,0"/> 
       </StatusBar> 
      </DockPanel> 
      <Border BorderThickness="0,1,0,0" Margin="0,35,0,0" BorderBrush="#f7000000"> 

      </Border> 
     </Grid> 
    </Border> 
</Grid> 
</Window> 

Kod CS

public partial class MainWindow : Window 
{ 
    private const int WM_DWMCOMPOSITIONCHANGED = 0x031E; 
    private const int DWM_BB_ENABLE = 0x1; 

    [StructLayout(LayoutKind.Sequential)] 
    private struct DWM_BLURBEHIND 
    { 
     public int dwFlags; 
     public bool fEnable; 
     public IntPtr hRgnBlur; 
     public bool fTransitionOnMaximized; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    private struct MARGINS 
    { 
     public int cxLeftWidth; 
     public int cxRightWidth; 
     public int cyTopHeight; 
     public int cyBottomHeight; 
    } 

    [DllImport("dwmapi.dll", PreserveSig = false)] 
    private static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind); 
    [DllImport("dwmapi.dll")] 
    private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins); 
    [DllImport("dwmapi.dll", PreserveSig = false)] 
    private static extern bool DwmIsCompositionEnabled(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     SourceInitialized += OnSourceInitialized; 
    } 

    private void OnSourceInitialized(object sender, EventArgs eventArgs) 
    { 
     var hwnd = new WindowInteropHelper(this).Handle; 
     var hs = HwndSource.FromHwnd(hwnd); 
     hs.CompositionTarget.BackgroundColor = System.Windows.Media.Colors.Transparent; 

     var margins = new MARGINS(); 
     margins.cxLeftWidth = margins.cxRightWidth = margins.cyTopHeight = margins.cyBottomHeight = -1; 

     DwmExtendFrameIntoClientArea(hwnd, ref margins); 

     DWM_BLURBEHIND bbh = new DWM_BLURBEHIND(); 
     bbh.fEnable = true; 
     bbh.dwFlags = DWM_BB_ENABLE; 
     DwmEnableBlurBehindWindow(hwnd, ref bbh); 
    } 

    private void TriggerMinimize(object sender, RoutedEventArgs e) 
    { 
     WindowState = System.Windows.WindowState.Minimized; 
    } 

    private void TriggerMoveWindow(object sender, MouseEventArgs e) 
    { 
     if (e.LeftButton == MouseButtonState.Pressed) 
     { 
      if (WindowState == System.Windows.WindowState.Maximized) 
      { 
       WindowState = System.Windows.WindowState.Normal; 
       double pct = PointToScreen(e.GetPosition(this)).X/System.Windows.SystemParameters.PrimaryScreenWidth; 
       Top = 0; 
       Left = e.GetPosition(this).X - (pct * Width); 
      } 

      Application.Current.MainWindow.DragMove(); 
     } 
    } 

    private void TriggerMaximize(object sender, EventArgs e) 
    { 
     if (WindowState == System.Windows.WindowState.Maximized) 
     { 
      WindowState = System.Windows.WindowState.Normal; 
      btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Webdings"); 
      btnMaximize.Content = "c"; 
     } 
     else if (WindowState == System.Windows.WindowState.Normal) 
     { 
      WindowState = System.Windows.WindowState.Maximized; 
      btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Wingdings"); 
      btnMaximize.Content = "r"; 
      InvalidateVisual(); 
     } 
    } 

    private void TriggerClose(object sender, RoutedEventArgs e) 
    { 
     Close(); 
    } 

    private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) 
    { 
     this.Height += e.VerticalChange; 
     this.Width += e.HorizontalChange; 
    } 
} 

można zobaczyć wynik:

https://i.stack.imgur.com/Rvtp3.gif

+0

Słodki! Dzięki. To działa. – Mike

Powiązane problemy