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

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

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

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

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

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


답변

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>

결과는 다음과 같습니다.


답변

테두리없는 창을 만들려고 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>

감사합니다!


답변

받아 들여지는 대답은 매우 사실이지만 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 창


답변

여기에 샘플 :

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


답변

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

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

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


답변