2009-03-04 21 views
73

Nếu bạn đặt ResizeMode="CanResizeWithGrip" trên WPF Window sau đó một va li thay đổi kích thước được hiển thị ở góc dưới bên phải, như sau:Làm thế nào để tạo một cửa sổ WPF mà không có đường viền có thể thay đổi kích thước chỉ bằng một cái kẹp?

Nếu bạn đặt WindowStyle="None" cũng thanh tiêu đề sẽ biến mất nhưng những gì còn lại cạnh vát màu xám cho đến khi bạn đặt ResizeMode="NoResize". Thật không may, với sự kết hợp của các thuộc tính được thiết lập, sự thay đổi kích thước cũng biến mất.

Tôi đã ghi đè số ControlTemplate của Window qua tùy chỉnh Style. Tôi muốn chỉ định đường viền của cửa sổ, và tôi không cần người dùng có thể thay đổi kích thước cửa sổ từ tất cả bốn phía, nhưng tôi cần một sự thay đổi kích thước.

Ai đó có thể chi tiết một cách đơn giản để đáp ứng tất cả các tiêu chí này?

  1. Đừng có đường viền trên Window ngoài một trong những tôi chỉ định bản thân mình trong một ControlTemplate.
  2. Làm có tay cầm thay đổi kích thước đang hoạt động ở góc dưới bên phải.
  3. Không có thanh tiêu đề.
+2

Xin lưu ý rằng Allowtransperency tạo ra rò rỉ bộ nhớ. Vì vậy, tránh sử dụng nó. Vui lòng tham khảo http://social.msdn.microsoft.com/Forums/en/wpf/thread/fc76b788-c4a6-45f4-896e-5646dffd2155 –

+1

@DipeshBhatt Tôi không thể tìm thấy bất kỳ lời giải thích nào cho xác nhận quyền sở hữu đó trong liên kết mà bạn được cung cấp.có thể bạn muốn đăng liên kết https://social.msdn.microsoft.com/Forums/vstudio/en-US/69bae823-dbe9-4a38-b964-e87b71195bb6/window-on-seperate-thread-memory-leak-when- allowtransparencytrue-progress-window? forum = wpf – itsho

Trả lời

152

Nếu bạn đặt AllowsTransparency tài sản trên Window (ngay cả khi không thiết lập bất kỳ giá trị minh bạch) biên giới sẽ biến mất và bạn chỉ có thể thay đổi kích thước thông qua sự kìm kẹp.

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

quả trông giống như:

+0

Táo tinh khiết Tôi biết điều này - Tôi đã chơi với cùng một điều khiển đặt mình vào chiều nay. :) – ZombieSheep

+2

Chà, tôi sẽ không mong đợi điều này, nhưng nó hoàn toàn tiện dụng cho việc tạo của bạn-riêng-sau-ghi-trong-phút-phút, cảm ơn :) –

+3

AllowTransparency có một số nhược điểm mặc dù, Windows không còn có thể điều khiển cửa sổ máy chủ lưu trữ như vậy là WebBrowser, Thông thường buộc hiển thị phần mềm, đã báo cáo rò rỉ bộ nhớ. Xem giải pháp thay thế của tôi bên dưới. – Wobbles

6

mẫu ở đây:

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

Bạn nên bao gồm giải thích ngắn gọn về cách mã hoạt động. – M456

33

Trong khi trả lời chấp nhận là rất đúng, chỉ muốn chỉ ra rằng AllowTransparency có một số sự sụp đổ. Nó không cho phép các điều khiển cửa sổ con xuất hiện, tức là WebBrowser, và nó thường buộc các phần mềm dựng hình có thể có các hiệu ứng hiệu suất tiêu cực.

Có một công việc tốt hơn xung quanh.

Khi bạn muốn tạo cửa sổ không có đường viền có thể định lại và có thể lưu trữ điều khiển WebBrowser hoặc điều khiển Khung được trỏ đến URL bạn không thể, nội dung của điều khiển được hiển thị trống.

Tôi đã tìm được giải pháp thay thế; trong cửa sổ, nếu bạn đặt WindowStyle thành None, ResizeMode thành NoResize (chịu với tôi, bạn vẫn có thể thay đổi kích thước khi hoàn thành), sau đó chắc chắn rằng bạn đã UNCHECKED AllowTransparency, bạn sẽ có một cửa sổ có kích thước tĩnh không có viền và sẽ hiển thị điều khiển trình duyệt.

Bây giờ, bạn có thể vẫn muốn có thể thay đổi kích cỡ đúng không?Vâng, chúng tôi có thể để điều đó với một cuộc gọi 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); 
    } 

Và thì đấy, Một cửa sổ WPF không có biên giới và vẫn di chuyển và thay đổi kích thước mà không làm mất khả năng tương thích với với các điều khiển như WebBrowser

+0

Làm thế nào chúng ta nên đi về nếu chúng ta muốn thay đổi kích cỡ từ tất cả các bên, không chỉ dưới cùng bên phải, nhưng vẫn muốn không có biên giới có thể nhìn thấy? – Daniel

+5

Dưới đây là các giá trị wParam khác, chỉ cần gán sự kiện mới để các đối tượng giao diện người dùng mới sử dụng những khi cần thiết 'tin enum ResizeDirection { Left = 61.441, Ngay = 61.442, Lên trên = 61.443, topleft = 61.444, topright = 61.445 , Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, } ' – Wobbles

+0

Điều này làm việc tuyệt vời cho tôi, với một ngoại lệ mặc dù một khi bạn có NoResize bạn không thể chụp cửa sổ bằng cách kéo nó lên trên cùng nữa. – CJK

43

Tôi đã cố gắng để tạo ra một không biên giới cửa sổ với WindowStyle="None" nhưng khi tôi thử nghiệm nó, dường như xuất hiện một thanh màu trắng ở phía trên, sau khi một số nghiên cứu nó dường như là một "border Thay đổi kích thước", đây là một hình ảnh (tôi nhấn mạnh bằng màu vàng):

The Challenge

Sau khi một số nghiên cứu trên internet, và rất nhiều các giải pháp khó khăn không XAML, tất cả các giải pháp mà tôi thấy là mã sau trong C# và rất nhiều dòng mã, tôi thấy gián tiếp các giải pháp ở đây: Maximum custom window loses drop shadow effect

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

Note: Bạn cần sử dụng khung công tác .NET 4.5 hoặc nếu bạn đang sử dụng phiên bản cũ hơn, hãy sử dụng WPFShell, chỉ cần tham khảo vỏ và sử dụng Shell:WindowChrome.WindowChrome thay thế.

Tôi đã sử dụng thuộc tính WindowChrome của Window, nếu bạn sử dụng màu trắng "đường viền thay đổi kích thước" này biến mất, nhưng bạn cần xác định một số thuộc tính để hoạt động chính xác.

CaptionHeight: Đây là chiều cao của khu vực chú thích (thanh tiêu đề) cho phép Aero Snap, thao tác nhấp đúp như một thanh tiêu đề bình thường. Đặt giá trị này thành 0 (không) để làm cho các nút hoạt động.

ResizeBorderThickness: Đây là độ dày ở cạnh của cửa sổ là nơi bạn có thể thay đổi kích thước cửa sổ. Tôi đặt đến 5 vì tôi thích con số đó, và bởi vì nếu bạn đặt không khó để thay đổi kích thước cửa sổ.

Sau khi sử dụng mã ngắn này kết quả là thế này:

The Solution

Và bây giờ, các đường viền màu trắng biến mất mà không sử dụng ResizeMode="NoResize"AllowsTransparency="True", cũng nó cho thấy một cái bóng trong cửa sổ.

Sau đó, tôi sẽ giải thích cách thực hiện các nút (Tôi không sử dụng hình ảnh cho các nút) dễ dàng với mã đơn giản và ngắn, Im mới và tôi nghĩ rằng tôi có thể đăng lên codeproject, bởi vì ở đây tôi đã làm ' t tìm nơi đăng bài hướng dẫn.

Có thể có giải pháp khác (tôi biết rằng có những giải pháp khó và khó cho noobs như tôi) nhưng điều này phù hợp với các dự án cá nhân của tôi.

Đây là mã hoàn chỉnh

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

Cảm ơn bạn!

+1

Vâng, Kudos cho cái này! Điều này là bởi đến nay các giao dịch đơn giản nhất/không có câu trả lời của chủ đề này! Nên nhận được nhiều hơn 'lên' bỏ phiếu. Tôi phải thừa nhận rằng tôi là loại tự hoại về nó, đặc biệt là về những gì đang xảy ra dưới mui xe. Tôi thậm chí đã kiểm tra cây WFP và nó chắc chắn trông giống như sự minh bạch không được thêm trở lại. Ngay cả các điều khiển khéo léo như màn hình 'WebBrowser' chỉ hiển thị tốt. Tôi đã có một vấn đề đóng băng rendering bằng cách sử dụng minh bạch khi ứng dụng đã được rất nhiều căng thẳng ... Vâng, điều này không xảy ra với giải pháp này. Tôi nghĩ rằng nó có thể là thời gian để nghỉ hưu giải pháp @Wobbles! – VeV

+1

Có vẻ như điều này vẫn có thể cần interop để kéo cửa sổ nếu tôi giải thích việc sử dụng sự kiện 'Rectangle_PreviewMouseDown' đúng cách. – Wobbles

+0

Điều này có thể không hoạt động trong <= Win 8.1, đã thấy một số kết quả kỳ lạ trong máy ảo của tôi. Windows 7 & 8 là những mối quan tâm chính khi họ làm điều Aero biên giới ngu ngốc. – Wobbles

Các vấn đề liên quan