Pergunta

Quando um único clique um ícone de notificação na Vista (como os ícones de rede ou som) que você é apresentado com um diálogo ainda captionless delimitada ( http://i.msdn.microsoft.com/Aa511448.NotificationArea22 (pt-br, MSDN.10) .png ):

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

Como posso emular estes em WPF? Criando uma nova janela e definindo WindowStyle para "Nenhum" e ResizeMode para "CanResize" produz um resultado próximo, exceto que o quadro é um pouco magra demais eo diálogo é redimensionável, o que é indesejável. Definir ResizeMode para resultados "noresize" em uma janela com nenhuma borda Aero (apenas uma 2px borda fina linha sólida).

Foi útil?

Solução 2

Eu finalmente descobri-lo: Se você definir WindowStyle para "Nenhum" e ResizeMode para "CanResize", então você vai ter a borda espessa correta sem uma legenda, o único engate é que você ainda pode redimensionar a janela

Felizmente, este problema é facilmente corrigidas pela manipulação WM_NCHITTEST para a instância 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;
}

Por nunca deixando o Windows sabe que o cursor está em uma borda, nós nunca será presenteado com um cursor de redimensionamento.

Outras dicas

O truque é adicionar o limite de seu self. Eu fiz isso, fazendo o principal elemento de conteúdo de um DockPanel e adicionar uma borda. Você pode usar a fronteira para personalizar a aparência para combinar as janelas Vista estilo. Eu não sou bom com as cores, então não posso citar que um particular, mas usados ??Cinzento como um exemplo.

Tente o seguinte

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

O que você precisa é especificar a combinação certa de estilos de janela, WPF não expor todas as opções disponíveis no Windows, mas você pode configurá-los você mesmo usando pinvoke.

Eu não estou em uma máquina com o Vista agora, então eu não posso combinação estilo de teste para ver o que dá a aparência correta, mas a lista de estilos (em C #) é aqui http://pinvoke.net/default.aspx/user32/GetWindowLong.html

em que você está classe Window:

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

eu percebi que eu postar o que eu vim acima com a medida. Isso fica bem perto:

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

É claro que eles estão usando mais do que apenas uma transparência na ActiveWindowBorderColor desenhar no meio da fronteira. Parece que a top 1/4 tem uma sobreposição de branco, enquanto a parte inferior 3/4 tem uma capa preta. Também a fronteira exterior tem uma cor de destaque nas bordas direita e inferior. Se eu fosse fazer isso de verdade eu iria criar um UserControl que deriva de Fronteira para lidar com todos os pequenos detalhes como esse (e permitam-me para redimensionar se eu quiser) e jogar o estilo da janela em um dicionário de recursos.

Há uma solução em código postado aqui . Eu vou olhar para fazê-lo em XAML reta, porém, deve haver uma maneira de denominar sua borda da janela de modo que parece perto. Você também deve dar uma olhada em este para uma melhor explicação do que o post no fórum está fazendo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top