Question

Quand un simple clic sur une icône de notification dans Vista (comme le réseau ou les icônes sonores) vous sont présentés avec une boîte de dialogue bordée encore captionless ( http://i.msdn.microsoft.com/Aa511448.NotificationArea22 (fr-fr, MSDN.10) .png ):

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

Comment puis-je imiter ces derniers dans WPF? Création d'une nouvelle fenêtre et mise WindowStyle « Aucun » et ResizeMode à « CanResize » produit un résultat proche, sauf que le cadre est un peu trop mince et la boîte de dialogue est redimensionnable, ce qui est indésirable. Réglage resizeMode aux résultats de « noresize » dans une fenêtre sans bordure Aero (juste une mince bordure continue 2px.)

Était-ce utile?

La solution 2

Je me suis finalement dehors: Si vous définissez WindowStyle sur « Aucun » et ResizeMode à « CanResize » alors vous aurez la frontière épaisse correcte sans légende, le seul problème est que vous pouvez toujours redimensionner la fenêtre

Heureusement, ce problème est facilement corrigé par la manipulation WM_NCHITTEST pour votre exemple Window:

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;
}

En ne jamais laisser de Windows savoir que le curseur est sur une frontière, nous ne serons jamais présenté avec un curseur de redimensionnement.

Autres conseils

L'astuce est d'ajouter la frontière de votre auto. Je l'ai fait en faisant le principal élément de contenu et un DockPanel ajout d'une bordure. Vous pouvez utiliser la frontière pour personnaliser l'apparence pour correspondre aux fenêtres style Vista. Je ne suis pas bon avec des couleurs donc je ne peux nommer qu'un particulier mais utilisé gris comme exemple.

Effectuez les opérations suivantes

<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>

Qu'est-ce que vous avez besoin est de spécifier la bonne combinaison de styles de fenêtre, WPF ne pas exposer toutes les options disponibles dans Windows, mais vous pouvez les régler en utilisant PInvoke vous.

Je ne suis pas une machine Vista en ce moment je ne peux pas tester la combinaison de style pour voir ce qui donne l'apparence correcte mais la liste des styles (en C #) est ici http://pinvoke.net/default.aspx/user32/GetWindowLong.html

vous appartient à la classe de fenêtre:

[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);
}

Je pensais que je poste ce que je suis venu avec jusqu'à présent. Cela devient assez proche:

<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>

ils sont clairement utilisent plus que juste une transparence sur la ActiveWindowBorderColor de tirer au milieu de la frontière. Il semble que le 1/4 haut a un revêtement blanc tandis que le 3/4 inférieur a un revêtement noir. Aussi la bordure extérieure a une couleur d'accent sur les bords droit et inférieur. Si je devais le faire pour de vrai, je voudrais créer un UserControl qui dérive de la frontière pour gérer tous les petits détails comme ça (et me permettre de changer la taille si je veux) et jette le style de la fenêtre dans un dictionnaire de ressources.

Il y a une solution dans le code affiché ici . Je vais examiner le faire en XAML droite cependant, il devrait y avoir un moyen de style de votre bordure de la fenêtre il ressemble beaucoup. Vous devriez aussi jeter un oeil à cette pour une meilleure explication de ce que le poste de forum fait.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top