Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有阴影VS2012样式的WPF无边框窗口_C#_Wpf_User Interface_Visual Studio 2012 - Fatal编程技术网

C# 具有阴影VS2012样式的WPF无边框窗口

C# 具有阴影VS2012样式的WPF无边框窗口,c#,wpf,user-interface,visual-studio-2012,C#,Wpf,User Interface,Visual Studio 2012,我正在尝试创建一个类似Visual Studio 2012的应用程序。我曾经删除过窗口边框,并在xaml中更改了边框颜色 我不知道怎么画窗户的阴影,这里你可以看到我说的截图: 正如你所看到的,有一个阴影,它的颜色也是边框的颜色 您知道如何使用WPF实现它吗?这被称为“Metro风格”(Windows 8风格)。我认为这篇代码项目文章对您来说很有趣,它将帮助您 您可以尝试,它是根据MIT许可证授权的,包括ApplicationBar和ToastNotification类,或者也可以从CodePl

我正在尝试创建一个类似Visual Studio 2012的应用程序。我曾经删除过窗口边框,并在xaml中更改了边框颜色

我不知道怎么画窗户的阴影,这里你可以看到我说的截图:

正如你所看到的,有一个阴影,它的颜色也是边框的颜色

您知道如何使用WPF实现它吗?

这被称为“Metro风格”(Windows 8风格)。我认为这篇代码项目文章对您来说很有趣,它将帮助您

您可以尝试,它是根据MIT许可证授权的,包括ApplicationBar和ToastNotification类,或者也可以从CodePlex获得

这是一个关于极乐世界的很棒的教程,我认为它对你有帮助

对于阴影,只需从XAML中的
网格
位图效果
添加到
边框

<Grid>
    <Border BorderBrush="#FF006900" BorderThickness="3" Height="157" HorizontalAlignment="Left" Margin="12,12,0,0" Name="border1" VerticalAlignment="Top" Width="479" Background="#FFCEFFE1" CornerRadius="20, 20, 20, 20">
        <Border.BitmapEffect>
          <DropShadowBitmapEffect Color="Black" Direction="320" ShadowDepth="10" Opacity="0.5" Softness="5" />
        </Border.BitmapEffect>
        <TextBlock Height="179" Name="textBlock1" Text="Hello, this is a beautiful DropShadow WPF Window Example." FontSize="40" TextWrapping="Wrap" TextAlignment="Center" Foreground="#FF245829" />
    </Border>
</Grid>

更新(10月17日) 四年过去了,我有兴趣再次解决这个问题,因此我一次又一次地和MahApps.Metro混在一起。My ModernChrome库提供了一个类似Visual Studio 2017的自定义窗口:

由于您很可能只对发光边框部分感兴趣,您应该使用MahApps.Metro本身,或者查看我如何创建一个类
GlowWindowBehavior
,该类将发光边框附加到我的自定义
ModernWindow
类。它严重依赖于MahApps.Metro的一些内部结构以及两个依赖属性
GlowBrush
NonActiveGlowBrush

如果您只想在自定义应用程序中包含发光边框,只需引用MahApps.Metro并复制my
GlowWindowBehavior.cs
,然后创建自定义窗口类并相应地调整引用。这最多是15分钟

这个问题和我的答案经常被访问,因此我希望您会发现我最新的正确解决方案很有用:)


原职(二月十三日) 我一直在开发这样一个库来复制Visual Studio 2012用户界面。定制chrome并不是那么难,但是你需要注意的是这个发光的边框,它很难实现。您可以说,将窗口的背景色设置为透明,并将主网格的填充设置为30px左右。网格周围的边框可以是彩色的,并与彩色阴影效果相关联,但这种方法会强制您将
allowTransparency
设置为true,这会大大降低应用程序的视觉性能,这是您绝对不想做的事情

我目前的方法是创建这样一个窗口,它在边框上有一个彩色阴影效果,是透明的,但没有任何内容。每当我的主窗口的位置改变时,我只更新保存边框的窗口的位置。因此,最后我处理两个窗口,其中包含假边界将是主窗口的一部分的消息。这是必要的,因为DWM库没有提供一种为windows提供彩色阴影效果的方法,我认为VisualStudio2012也像我尝试的那样提供了类似的效果

为了扩展这篇文章,提供更多信息:Office 2013的做法有所不同。窗口周围的边框只有1px厚且颜色鲜艳,但阴影是由DWM使用如下代码绘制的。如果你不需要蓝色/紫色/绿色的边框,也不需要普通的边框,这就是我选择的方法!只是不要将
allowsttransparency
设置为true,否则将丢失

这是我的窗口的屏幕截图,用奇怪的颜色突出显示它的外观:


以下是一些关于如何开始的提示

请记住,我的代码相当长,因此我只能向您展示要做的基本事情,您至少应该能够以某种方式开始。首先,我将假设我们已经以某种方式设计了主窗口(手动或使用我昨天试用的
MahApps.Metro
包-对源代码进行了一些修改,这非常好(1)),我们目前正在努力实现发光阴影边框,从现在起,我将称之为
GlowWindow
。最简单的方法是使用以下XAML代码创建一个窗口

<Window x:Class="MetroUI.Views.GlowWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="GlowWindow"
    Title="" Width="300" Height="100" WindowStartupLocation="Manual"
    AllowsTransparency="True" Background="Transparent" WindowStyle="None"
    ShowInTaskbar="False" Foreground="#007acc" MaxWidth="5000" MaxHeight="5000">
    <Border x:Name="OuterGlow" Margin="10" Background="Transparent"
            BorderBrush="{Binding Foreground, ElementName=GlowWindow}"
            BorderThickness="5">
        <Border.Effect>
            <BlurEffect KernelType="Gaussian" Radius="15" RenderingBias="Quality" />
        </Border.Effect>
    </Border>
</Window>
此方法主要在我已附加到主窗口的自定义
WndProc
中调用:

/// <summary>
/// An application-defined function that processes messages sent to a window. The WNDPROC type
/// defines a pointer to this callback function.
/// </summary>
/// <param name="hwnd">A handle to the window.</param>
/// <param name="uMsg">The message.</param>
/// <param name="wParam">Additional message information. The contents of this parameter depend on
/// the value of the uMsg parameter.</param>
/// <param name="lParam">Additional message information. The contents of this parameter depend on
/// the value of the uMsg parameter.</param>
/// <param name="handled">Reference to boolean value which indicates whether a message was handled.
/// </param>
/// <returns>The return value is the result of the message processing and depends on the message sent.
/// </returns>
private IntPtr WindowProc(IntPtr hwnd, int uMsg, IntPtr wParam, IntPtr lParam, ref bool handled) {
    // BEGIN UNMANAGED WIN32
    switch((WinRT.Message)uMsg) {
        case WinRT.Message.WM_SIZE:
            switch((WinRT.Size)wParam) {
                case WinRT.Size.SIZE_MAXIMIZED:
                    this.Left = this.Top = 0;
                    if(!this.IsMaximized)
                        this.IsMaximized = true;
                    this.UpdateChrome();
                    break;
                case WinRT.Size.SIZE_RESTORED:
                    if(this.IsMaximized)
                        this.IsMaximized = false;
                    this.UpdateChrome();
                    break;
            }
            break;

        case WinRT.Message.WM_WINDOWPOSCHANGING:
            WinRT.WINDOWPOS windowPosition = (WinRT.WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WinRT.WINDOWPOS));
            Window handledWindow = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
            if(handledWindow == null)
                return IntPtr.Zero;
            bool hasChangedPosition = false;
            if(this.IsMaximized == true && (this.Left != 0 || this.Top != 0)) {
                windowPosition.x = windowPosition.y = 0;
                windowPosition.cx = (int)SystemParameters.WorkArea.Width;
                windowPosition.cy = (int)SystemParameters.WorkArea.Height;
                hasChangedPosition = true;
                this.UpdateChrome();
                this.UpdateGlowWindow();
            }
            if(!hasChangedPosition)
                return IntPtr.Zero;
            Marshal.StructureToPtr(windowPosition, lParam, true);
            handled = true;
            break;
    }
    return IntPtr.Zero;
    // END UNMANAGED WIN32
}
但我们仍然会遇到一些问题-当您将鼠标移到GlowWindow上并左键单击时,它将被激活并获得焦点,这意味着它将与主窗口重叠,如下所示:

为了防止这种情况发生,只需捕捉边框的
激活事件
,并将主窗口置于前台即可

您应该如何做到这一点?

我建议不要尝试这种方法——我花了大约一个月的时间才实现了我想要的,但仍然存在一些问题,因此我会选择Office 2013那样的方法——彩色边框和DWM API调用的常规阴影——没有其他方法,但仍然看起来不错



(1) 我刚刚编辑了一些文件以启用窗口周围的边框,这在窗口8上对我是禁用的。此外,我还操纵了标题栏的
填充
,使其看起来不像是在原地被sqeezed,最后我更改了All Caps属性,以模仿Visual Studio呈现标题的方式。到目前为止,
MahApps.Metro
是一种更好的绘制主窗口的方法,因为它甚至支持AeroSnap,我无法用普通的P/Invoke调用实现。

您可以使用这个简单的xaml代码

<Window x:Class="VS2012.MainWindow" 
         xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
         xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml 
         Title="MainWindow" 
         Height="100" Width="200" 
         AllowsTransparency="True" WindowStyle="None" Background="Transparent"> 
<Border BorderBrush="DarkOrange" BorderThickness="1" Background="White" Margin="5">
         <Border.Effect>
                <DropShadowEffect ShadowDepth="0" BlurRadius="5" Color="DarkOrange"/>
         </Border.Effect>
</Border>
</Window> 

我试图获得相同的效果,我的应用程序使用.NET 4,因此我无法直接使用
WindowChrome
(因此,我使用库来获得相同的效果
this.Loaded += delegate {
    WindowInteropHelper wndHelper = new WindowInteropHelper(this);
    int exStyle = (int)WinRT.GetWindowLong(wndHelper.Handle, (int)WinRT.GetWindowLongFields.GWL_EXSTYLE);
    exStyle |= (int)WinRT.ExtendedWindowStyles.WS_EX_TOOLWINDOW;
    WinRT.SetWindowLong(wndHelper.Handle, (int)WinRT.GetWindowLongFields.GWL_EXSTYLE, (IntPtr)exStyle);
};
<Window x:Class="VS2012.MainWindow" 
         xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
         xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml 
         Title="MainWindow" 
         Height="100" Width="200" 
         AllowsTransparency="True" WindowStyle="None" Background="Transparent"> 
<Border BorderBrush="DarkOrange" BorderThickness="1" Background="White" Margin="5">
         <Border.Effect>
                <DropShadowEffect ShadowDepth="0" BlurRadius="5" Color="DarkOrange"/>
         </Border.Effect>
</Border>
</Window> 
<Window x:Class="MyProject.MiniWindow"
    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:MyProject"
    mc:Ignorable="d" 
    WindowStyle="None" 
    Title="MiniWindow" Background="Transparent"
    Height="200" Width="200" 
    >

<WindowChrome.WindowChrome>
    <WindowChrome 
    CaptionHeight="0"
    ResizeBorderThickness="4" />
</WindowChrome.WindowChrome>

<Grid Margin="0">
    <Border BorderThickness="3">
        <Border BorderThickness="1" Margin="0" BorderBrush="#ff007acc">
            <Border.Effect>
                <DropShadowEffect Color="#ff007acc" Direction="132" ShadowDepth="0" BlurRadius="8" />
            </Border.Effect>
            <Grid   Background="#ff2d2d30">
                
            </Grid>
        </Border>
    </Border>
    
    
</Grid>