Pregunta

Cuando un solo clic en un icono de notificación en Vista (como la red o iconos de sonido) que se presentan con un cuadro de diálogo todavía captionless bordeado ( http://i.msdn.microsoft.com/Aa511448.NotificationArea22 (es-es, MSDN.10) .png ):

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

¿Cómo puedo emular a estos en WPF? La creación de una nueva ventana y el establecimiento de WindowStyle en "None" y ResizeMode a "CanResize" produce un resultado cercano a excepción de que el marco es un poco demasiado finas y el diálogo es de tamaño variable, lo cual es indeseable. Ajuste a resultados ResizeMode "noresize" en una ventana sin bordes Aero (sólo una delgada línea sólida 2px.)

¿Fue útil?

Solución 2

Finalmente lo descubrí: Si establece WindowStyle en "None" y ResizeMode a "CanResize" Luego le ponen el borde grueso correcto sin un título, el único problema es que todavía se puede cambiar el tamaño de la ventana

Afortunadamente este problema es fácilmente rectificado por el manejo WM_NCHITTEST para su Window ejemplo:

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

Por dejar nunca de Windows saben que el cursor se encuentra en una frontera, que nunca serán presentados con un cursor de cambio de tamaño.

Otros consejos

El truco es agregar el borde de su auto. Así lo hice, haciendo que el elemento de la página principal de un DockPanel y agregar un borde. Puede utilizar la frontera para personalizar el aspecto para que coincida con las ventanas de estilo de Vista. No soy bueno con los colores así que no puedo nombrar esa en particular sino que se utiliza como un ejemplo gris.

Pruebe lo siguiente

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

Lo que necesita es especificar la correcta combinación de estilos de ventana, WPF no expone todas las opciones disponibles en Windows, pero se les puede fijarse mediante PInvoke.

No estoy en una máquina de Vista en este momento, así que no puedo probar la combinación de estilo para ver lo que da la apariencia correcta, pero la lista de estilos (en C #) está aquí http://pinvoke.net/default.aspx/user32/GetWindowLong.html

en el que eres la clase de ventana:

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

Me imaginé que había puesto lo que he encontrado hasta el momento. Esto pone muy cerca:

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

Es evidente que están utilizando más que una transparencia en la ActiveWindowBorderColor para dibujar la mitad de la frontera. Parece que el cuarto superior tiene una capa blanca, mientras que la parte inferior de 3/4 tiene un recubrimiento negro. También la frontera exterior tiene un acento de color en los bordes derecho e inferior. Si tuviera que hacer esto de verdad me gustaría crear un control de usuario que se deriva de Frontera para manejar todos los pequeños detalles como que (y me permite cambiar el tamaño si quiero) y tirar el estilo de la ventana en un diccionario de recursos.

No es una solución de código publicado aquí . Voy a mirar en hacer que en XAML recta sin embargo, no debe haber una forma de estilo de su borde de la ventana para que se vea de cerca. También debe echar un vistazo a este para una mejor explicación de lo que el mensaje del foro está haciendo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top