그립을 통해서만 크기를 조정할 수있는 테두리없이 WPF 창을 만드는 방법은 무엇입니까?


94

ResizeMode="CanResizeWithGrip"WPF에서 설정하면 Window아래와 같이 오른쪽 하단 모서리에 크기 조정 그립이 표시됩니다.

WindowStyle="None"마찬가지로 설정 하면 제목 표시 줄이 사라지지만 설정할 때까지 회색 경 사진 가장자리가 유지됩니다 ResizeMode="NoResize". 안타깝게도이 속성 조합을 설정하면 크기 조정 그립도 사라집니다.

나는 사용자 정의를 통해 WindowControlTemplate를 재정의했습니다 Style. 창의 테두리를 직접 지정하고 싶습니다. 사용자가 네면에서 창 크기를 조정할 필요는 없지만 크기 조정 그립이 필요합니다.

누군가 이러한 기준을 모두 충족하는 간단한 방법을 자세히 설명 할 수 있습니까?

  1. Window에서 직접 지정한 테두리와는 별도로 테두리를 두지 마십시오ControlTemplate .
  2. 오른쪽 하단에있는 작업 크기 조정 그립이있다.
  3. 제목 표시 줄이 없습니다 .

3
Allowtransperency는 메모리 누수를 유발합니다. 따라서 사용하지 마십시오. social.msdn.microsoft.com/Forums/en/wpf/thread/…를
Dipesh Bhatt

1
@DipeshBhatt 제공하신 링크에서 해당 주장에 대한 설명을 찾을 수 없습니다. 링크를 게시하려고했을 수도 있습니다. social.msdn.microsoft.com/Forums/vstudio/en-US/…
itsho

창 스타일을 없음으로 설정했지만 상단의 회색 가장자리를 향하고있었습니다. ResizeMode = "NoResize"가 내 문제를 해결했습니다.
Surendra Shrestha

답변:


180

AllowsTransparency속성을 Window설정하면 (투명도 값을 설정하지 않더라도) 테두리가 사라지고 그립을 통해서만 크기를 조정할 수 있습니다.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="640" Height="480" 
    WindowStyle="None"
    AllowsTransparency="True"
    ResizeMode="CanResizeWithGrip">

    <!-- Content -->

</Window>

결과는 다음과 같습니다.


나는 이것을 알고 있었다. 나는 오늘 오후에 같은 컨트롤 세트로 연주하고 있었다. :)
ZombieSheep

2
와우, 감사합니다 :) 나는 이것을 기대하지 않을 것이다, 그러나 그것은 메이크업 - 네 - 자신의 포스트 - 그것 - 노트 -에 - 5 분 동안 완전히 편리
토마스 카프카

4
AllowTransparency에는 몇 가지 단점이 있지만 Windows는 더 이상 WebBrowser와 같은 하위 창 컨트롤을 호스팅 할 수 없습니다. 일반적으로 소프트웨어 렌더링을 강제하고 메모리 누수를보고했습니다. 아래의 해결 방법을 참조하십시오.
Wobbles 2014 년

테두리를 제거하려면 WindowStyle = "None"만 필요합니다. AllowsTransparency는 필요한 경우에만 발생하지만 테두리에는 영향을주지 않습니다.
Grault

2
@Grault는 창 헤더를 제거하지만 양식 주위에는 여전히 단색 테두리가 있습니다. AllowsTransparency는 테두리를 제거합니다.
Wobbles

78

테두리없는 창을 만들려고 WindowStyle="None"했지만 테스트했을 때 상단에 흰색 막대가 나타나는 것 같습니다. 몇 가지 조사를 한 후 "테두리 크기 조정"으로 표시됩니다. 여기에 이미지가 있습니다 (노란색으로 표시).

도전

인터넷을 통한 조사와 xaml이 아닌 여러 가지 어려운 솔루션, 내가 찾은 모든 솔루션은 C # 및 많은 코드 라인의 코드 뒤에서 간접적으로 해결책을 찾았습니다. 최대 사용자 지정 창에서 그림자 효과가 손실 됨

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

참고 : .NET 4.5 프레임 워크를 사용해야합니다. 이전 버전을 사용하는 경우 WPFShell을 사용하고 셸을 참조하고 Shell:WindowChrome.WindowChrome대신 사용하세요.

나는 WindowChromeWindow 의 속성을 사용했는데 이것을 사용하면 흰색 "resize border"가 사라지지만 제대로 작동하려면 몇 가지 속성을 정의해야합니다.

CaptionHeight : 일반 제목 표시 줄처럼 Aero 스냅, 더블 클릭 동작을 허용하는 캡션 영역 (헤더 바)의 높이입니다. 버튼이 작동하도록하려면이 값을 0 (영)으로 설정하십시오.

ResizeBorderThickness : 창의 크기를 조정할 수있는 창의 가장자리 두께입니다. 나는 그 숫자를 좋아하기 때문에 5에 넣었고 0을 넣으면 창 크기를 조정하기가 어렵 기 때문입니다.

이 짧은 코드를 사용한 후 결과는 다음과 같습니다.

해결책

그리고 지금, 흰색 테두리 사용하지 않고 사라 ResizeMode="NoResize"AllowsTransparency="True"또한 창에 그림자를 보여줍니다.

나중에 간단하고 짧은 코드로 쉽게 버튼 (버튼에 이미지를 사용하지 않았 음)을 만드는 방법을 설명 할 것입니다. Im new와 저는 코드 프로젝트에 게시 할 수 있다고 생각합니다. 튜토리얼을 게시합니다.

어쩌면 다른 해결책이있을 수도 있지만 (저와 같은 멍청한 사람들에게는 어렵고 어려운 해결책이 있다는 것을 알고 있습니다)하지만 이것은 제 개인 프로젝트에 적합합니다.

다음은 완전한 코드입니다.

<Window x:Class="MainWindow"
    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:Concursos"
    mc:Ignorable="d"
    Title="Concuros" Height="350" Width="525"
    WindowStyle="None"
    WindowState="Normal" 
    ResizeMode="CanResize"
    >
<WindowChrome.WindowChrome>
    <WindowChrome 
        CaptionHeight="0"
        ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

    <Grid>

    <Rectangle Fill="#D53736" HorizontalAlignment="Stretch" Height="35" VerticalAlignment="Top" PreviewMouseDown="Rectangle_PreviewMouseDown" />
    <Button x:Name="Btnclose" Content="r" HorizontalAlignment="Right" VerticalAlignment="Top" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
    <Button x:Name="Btnmax" Content="2" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,35,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
    <Button x:Name="Btnmin" Content="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,70,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>

</Grid>

감사합니다!


3
글쎄, 이것에 대한 찬사! 이것은이 스레드에 대한 가장 간단한 / 절대 절충 답변입니다! 훨씬 더 많은 '상승'투표를 받아야합니다. 나는 그것에 대해, 특히 후드 아래에서 일어나는 일에 대해 일종의 패혈증 이었다는 것을 인정해야합니다. WFP 트리도 확인했는데 투명도가 다시 추가되지 않은 것 같습니다. 'WebBrowser'와 같은 까다로운 컨트롤도 잘 표시됩니다. 앱이 많은 스트레스를 받았을 때 투명성을 사용하여 렌더링이 중단되는 문제가 발생했습니다.이 솔루션에서는 이런 일이 발생하지 않습니다. @Wobbles 솔루션을 은퇴 할 때가 된 것 같습니다!
VeV

1
Rectangle_PreviewMouseDown이벤트 사용을 올바르게 해석하면 창 드래그를 위해 interop이 여전히 필요할 수 있습니다 .
Wobbles

이것은 <= Win 8.1에서 작동하지 않을 수 있으며 내 VM에서 이상한 결과를 보았습니다. Windows 7 및 8은 어리석은 Aero 경계 작업을 수행하므로 주요 관심사입니다.
Wobbles

회신의 주셔서 감사합니다
페르난도 아구에게

안녕하세요 @FernandoAguirre, 이 관련 질문을 게시 했으며 답변이 있으면 감사 하겠습니다 .
sampathsris

39

받아 들여지는 대답은 매우 사실이지만 AllowTransparency에는 몇 가지 단점이 있음을 지적하고 싶습니다. WebBrowser와 같은 자식 창 컨트롤이 표시되는 것을 허용하지 않으며 일반적으로 성능에 부정적인 영향을 줄 수있는 소프트웨어 렌더링을 강제합니다.

그래도 더 나은 해결 방법이 있습니다.

크기를 조정할 수 있고 WebBrowser 컨트롤 또는 URL을 가리키는 프레임 컨트롤을 호스팅 할 수있는 테두리가없는 창을 만들려면 해당 컨트롤의 내용이 비어있는 것으로 표시됩니다.

그래도 해결 방법을 찾았습니다. 창에서 WindowStyle을 None, ResizeMode를 NoResize로 설정하면 (참여, 일단 완료되면 여전히 크기를 조정할 수 있음) UNCHECKED AllowsTransparency가 있는지 확인하십시오. 테두리가없는 정적 크기의 창이 표시됩니다 브라우저 컨트롤.

이제 여전히 오른쪽으로 크기를 조정할 수 있기를 원하십니까? interop 호출을 통해 다음과 같이 할 수 있습니다.

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

    //Attach this to the MouseDown event of your drag control to move the window in place of the title bar
    private void WindowDrag(object sender, MouseButtonEventArgs e) // MouseDown
    {
        ReleaseCapture();
        SendMessage(new WindowInteropHelper(this).Handle,
            0xA1, (IntPtr)0x2, (IntPtr)0);
    }

    //Attach this to the PreviewMousLeftButtonDown event of the grip control in the lower right corner of the form to resize the window
    private void WindowResize(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
    {
        HwndSource hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
        SendMessage(hwndSource.Handle, 0x112, (IntPtr)61448, IntPtr.Zero);
    }

그리고 짜잔, 테두리가없고 WebBrowser와 같은 컨트롤과의 호환성을 잃지 않고 이동 및 크기 조정이 가능한 WPF 창


오른쪽 하단뿐만 아니라 모든면에서 크기를 조정하고 테두리를 표시하지 않으려면 어떻게해야합니까?
Daniel

6
다음은 다른 wParam 값입니다. 필요에 따라 새 이벤트를 새 UI 개체에 할당하기 만하면됩니다.private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, TopLeft = 61444, TopRight = 61445, Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, }
Wobbles

NoResize를 사용하면 더 이상 창을 맨 위로 드래그하여 창을 스냅 할 수 없지만 한 가지 예외가 있지만 이것은 저에게 잘 작동합니다.
CJK

2
@CJK 사실이지만 의심 할 여지없이 Windows 메시지를 연결하여 처리 할 수 ​​있습니다.
Wobbles

창을 끌 수 없습니다. 왜 그런지 아세요? (크기 조정은 매력처럼 작동)
Li3ro

5

여기에 샘플 :

<Style TargetType="Window" x:Key="DialogWindow">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Border BorderBrush="Black" BorderThickness="3" CornerRadius="10" Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}" Background="Gray">
                        <DockPanel>
                            <Grid DockPanel.Dock="Top">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition></ColumnDefinition>
                                    <ColumnDefinition Width="50"/>
                                </Grid.ColumnDefinitions>
                                <Label Height="35" Grid.ColumnSpan="2"
                                       x:Name="PART_WindowHeader"                                            
                                       HorizontalAlignment="Stretch" 
                                       VerticalAlignment="Stretch"/>
                                <Button Width="15" Height="15" Content="x" Grid.Column="1" x:Name="PART_CloseButton"/>
                            </Grid>
                            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                                        Background="LightBlue" CornerRadius="0,0,10,10" 
                                        Grid.ColumnSpan="2"
                                        Grid.RowSpan="2">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition Width="20"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*"/>
                                        <RowDefinition Height="20"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <ResizeGrip Width="10" Height="10" Grid.Column="1" VerticalAlignment="Bottom" Grid.Row="1"/>
                                </Grid>
                            </Border>
                        </DockPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

23
코드 작동 방식에 대한 간략한 설명을 포함해야합니다.
M456

0

나는 @ fernando-aguirre WindowChrome가 일하는 데 사용하여 답을 얻는 데 어려움을 겪었습니다 . 내가 무시했기 때문에 그것은 내 경우에는 작동하지 않는 OnSourceInitialized에서 MainWindow베이스 클래스 메서드를 호출하지.

protected override void OnSourceInitialized(EventArgs e)
{
    ViewModel.Initialize(this);
    base.OnSourceInitialized(e); // <== Need to call this!
}

이것은 나를 아주 오랫동안 당혹스럽게했다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.