Frage

Wenn ein Benachrichtigungssymbol in Vista (wie das Netzwerk oder Sound Icons) ein einzelnen Klicken Sie mit einem grenzte noch captionless Dialog präsentiert werden ( http://i.msdn.microsoft.com/Aa511448.NotificationArea22 (de-de, MSDN.10) .png ):

http: //i.msdn. microsoft.com/Aa511448.NotificationArea22(en-us,MSDN.10).png

Wie kann ich emulieren diese in WPF? Erstellen Sie ein neues Fenster und Einstellung Window auf „None“ und ResizeMode auf „CanResize“ erzeugt ein knappes Ergebnis, außer dass der Rahmen etwas zu dünn ist und der Dialog ist veränderbar, was unerwünscht ist. Einstellen ResizeMode auf „noresize“ Ergebnisse in einem Fenster ohne Aero Grenze (nur eine dünne 2px gezogene Linie Grenze.)

War es hilfreich?

Lösung 2

Habe ich es endlich heraus: Wenn Sie Window auf „None“ und ResizeMode auf „CanResize“ gesetzt, dann werden Sie die richtige dicke Grenze ohne Beschriftung erhalten, das einzige Problem ist, dass Sie das Fenster noch die Größe verändern können.

Zum Glück dieses Problem leicht durch den Umgang mit WM_NCHITTEST für Ihre Window Instanz behoben ist:

private IntPtr _hwnd;

protected override void OnSourceInitialized(EventArgs e) {
    _hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    System.Windows.Interop.HwndSource.FromHwnd(_hwnd).AddHook(_WndProc);
    base.OnSourceInitialized(e);
}

private const int WM_NCHITTEST = 132;
private const int HTCLIENT = 1;

private IntPtr _WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
    // We should only receive messages for our own window handle.
    System.Diagnostics.Debug.Assert(hwnd == _hwnd);

    if (msg == WM_NCHITTEST) {
        handled = true;
        return (IntPtr)HTCLIENT;
    }
    return IntPtr.Zero;
}

Durch die nie im Stich gelassen von Windows weiß, dass der Cursor an einer Grenze ist, werden wir nie mit einer Größe ändern Cursor dargestellt werden.

Andere Tipps

Der Trick ist, die Grenze, um sich selbst hinzuzufügen. Ich tat dies, indem das Hauptinhaltselement ein DockPanel machen und das Hinzufügen einer Grenze. Sie können die Grenze verwenden um das Aussehen anpassen, um den Vista Style Fenster passen. Ich bin nicht gut mit Farben, damit ich nicht, dass insbesondere einen Namen kann aber verwendet Grau als Beispiel.

Versuchen Sie, die folgende

<Window x:Class="WpfApplication10.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" 
    Height="300" 
    Width="300"
    WindowStyle="None"
    ResizeMode="NoResize">
    <DockPanel>
        <Border
            BorderBrush="Gray"
            BorderThickness="5">

            <TextBlock>Here we go</TextBlock>

        </Border>
    </DockPanel>
</Window>

Was Sie brauchen, ist die richtige Kombination von Fensterstile angeben, nicht WPF nicht alle Optionen in Windows zur Verfügung aussetzen, aber man kann sie selbst mit pinvoke eingestellt.

Ich bin nicht auf einem Vista-Rechner jetzt so kann ich nicht Artkombination testen, um zu sehen, was das richtige Aussehen gibt, aber die Liste der Arten (in C #) ist hier http://pinvoke.net/default.aspx/user32/GetWindowLong.html

Du bist Window-Klasse:

[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 SWP_NOZORDER = 0x0004;
private const UInt32 SWP_NOREDRAW = 0x0008;
private const UInt32 SWP_NOACTIVATE = 0x0010;
private const UInt32 SWP_FRAMECHANGED = 0x0020;

public override void OnSourceInitialized(EventArgs e)
{
    IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;

    // set styles to a combination of WS_ flags and exstyles to a combination of WS_EX_ flags

    SetWindowLong(hwnd, GWL_STYLE, styles);
    SetWindowLong(hwnd, GWL_EXSTYLE, exstyles);

    // and to activate changes:
    SetWindowPos(hwnd,IntPtr.Zero,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED);
}

Ich dachte, ich würde schreiben, was ich mit so weit habe kommen. Dies wird ziemlich nahe:

<Window.Style>
    <Style TargetType="{x:Type Window}">
        <Setter Property="AllowsTransparency"       Value="True"            />
        <Setter Property="Background"           Value="{x:Null}"        />
        <Setter Property="BorderBrush"          Value="{x:Null}"        />
        <Setter Property="BorderThickness"      Value="0"           />
        <Setter Property="OverridesDefaultStyle"    Value="True"            />
        <Setter Property="ResizeMode"           Value="NoResize"        />
        <Setter Property="SizeToContent"        Value="WidthAndHeight"      />
        <Setter Property="WindowStyle"          Value="None"            />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Border BorderThickness="1" CornerRadius="4" Background="{x:Null}">
                        <Border.BorderBrush>
                            <SolidColorBrush Color="{x:Static SystemColors.WindowFrameColor}" Opacity="0.75" />
                        </Border.BorderBrush>
                        <Border BorderThickness="5" Background="{x:Null}">
                            <Border.BorderBrush>
                                <SolidColorBrush Color="{x:Static SystemColors.ActiveBorderColor}" Opacity="0.5" />
                            </Border.BorderBrush>
                            <Border BorderThickness="1" Background="White">
                                <Border.BorderBrush>
                                    <SolidColorBrush Color="{x:Static SystemColors.WindowFrameColor}" Opacity="0.75" />
                                </Border.BorderBrush>

                                <ContentPresenter />
                            </Border>
                        </Border>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Style>

Selbstverständlich sind sie mit mehr als nur eine Transparenz auf dem ActiveWindowBorderColor die Mitte der Grenze zu ziehen. Es scheint, dass die oberen 1/4 ein weißes Overlay hat, während die unteren 3/4 einen schwarzen Overlay hat. Auch der äußere Rand hat eine Akzentfarbe auf der rechten und unteren Rand. Wenn ich das richtig tun, würde ich ein Benutzersteuerelement erstellen, die von Border stammen wie das all die kleinen Details zu behandeln (und ich erlauben, um die Größe, wenn ich will) und das Fenster Stil in ein Ressourcenverzeichnis werfen.

Es gibt eine Lösung in Code geschrieben hier . Ich werde schauen es in gerade XAML zu tun, obwohl, sollte es eine Möglichkeit geben, Ihre Fensterrand, um Stil, so dass es nahe aussieht. Sie sollten auch einen Blick auf, diese für eine bessere Erklärung, was das Forum Post tut.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top