グリップのみでサイズ変更できる境界のないWPFウィンドウを作成する方法は?


94

ResizeMode="CanResizeWithGrip"WPF を設定すると、Window右下隅にサイズ変更グリップが次のように表示されます。

WindowStyle="None"同様に設定すると、タイトルバーは非表示になりますが、設定するまで灰色のベベルエッジは残りますResizeMode="NoResize"。残念ながら、このプロパティの組み合わせを設定すると、サイズ変更グリップも消えます。

私が上書きされているWindowのをControlTemplate習慣経由Style。自分でウィンドウの境界線を指定したいのですが、ユーザーがウィンドウの4辺すべてのサイズを変更できるようにする必要はありませんが、サイズ変更グリップは必要です。

誰かがこれらの基準のすべてを満たす簡単な方法を詳述できますか?

  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/…
itho

ウィンドウスタイルを[なし]に設定しましたが、上部の灰色の端に直面していました。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
うわー、これは期待していませんが、make-your-own-post-it-notes-in-5-minutesのおかげで完全に便利です。おかげで:)
トマーシュカフカ

4
ただし、AllowTransparencyにはいくつかの欠点がありますが、WindowsはWebBrowserなどのサブウィンドウコントロールをホストできなくなりました。通常はソフトウェアレンダリングを強制し、メモリリークが報告されています。以下の私の回避策を参照してください。
Wobbles 2014

境界線を取り除くために必要なのはWindowStyle = "None"だけです。AllowsTransparencyはたまたまそれを必要とするだけですが、国境には影響しません..
Grault

2
@Grault thatsはウィンドウヘッダーを取り除きますが、フォームの周りにはまだ実線の枠があります。AllowsTransparencyは境界を取り除きます。
2015年

78

私はボーダーレスウィンドウを作成しようとしました WindowStyle="None"が、テストしたところ、上部に白いバーが表示されたようです。調査の結果、「ボーダーのサイズ変更」のように見えます。ここに画像があります(黄色でマークしました)。

挑戦

インターネットでのいくつかの調査、および多くの難しい非XAMLソリューションの後、私が見つけたすべてのソリューションはC#のコードビハインドと多くのコード行であり、間接的にここでソリューションを見つけました: 最大カスタムウィンドウはドロップシャドウ効果を失います

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

注意 :.NET 4.5フレームワークを使用する必要があります。または、古いバージョンを使用している場合はWPFShellを使用し、シェルを参照してShell:WindowChrome.WindowChrome代わりに使用してください。

WindowChromeはWindow のプロパティを使用しましたが、これを使用すると、白い「サイズ変更枠」が消えますが、正しく機能するためにいくつかのプロパティを定義する必要があります。

CaptionHeight:これは、通常のタイトルバーと同じように、Aeroスナップ、ダブルクリック動作を可能にするキャプション領域(ヘッダー)の高さです。ボタンを機能させるには、これを0(ゼロ)に設定します。

ResizeBorderThickness:これは、ウィンドウのサイズを変更できるウィンドウの端の厚さです。私はその数が好きで、ゼロを入れるとウィンドウのサイズを変更するのが難しいので、5にしました。

この短いコードを使用すると、結果は次のようになります。

ソリューション

そして今、使用せずに白い境界線が消えました ResizeMode="NoResize"AllowsTransparency="True"、ウィンドウに影が表示されます。

後で、ボタンを操作する方法(ボタンに画像を使用しなかった)を簡単で短いコードで簡単に説明します。新しいので、コードプロジェクトに投稿できると思います。チュートリアルを投稿します。

たぶん別の解決策があります(私のような初心者には難しい解決策があることは知っています)が、これは私の個人的なプロジェクトには有効です。

ここに完全なコードがあります

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

1
Rectangle_PreviewMouseDownイベントの使用を適切に解釈すると、ウィンドウのドラッグに相互運用が必要になる可能性があります。
2016年

これはWin 8.1以下では機能しない可能性があります。私のVMで奇妙な結果が見られました。Windows 7&8は、バカなAero境界線のことをしているので、主要な懸念事項です。
2016年

お返事ありがとうございます
フェルナンドアギレ2016年

こんにちは@FernandoAguirre、私はこの関連する質問を投稿しました。回答がありましたら感謝します。
sampathsris

39

受け入れられた答えは真実ですが、AllowTransparencyにはいくつかの問題があることを指摘したいだけです。子ウィンドウコントロール、つまりWebBrowserの表示を許可せず、通常、ソフトウェアのレンダリングを強制し、パフォーマンスに悪影響を与える可能性があります。

しかし、より良い回避策があります。

サイズ変更可能な境界線のないウィンドウを作成し、WebBrowserコントロールまたは単純にできなかったURLを指すFrameコントロールをホストできるようにしたい場合、そのコントロールのコンテンツは空で表示されます。

ただし、回避策を見つけました。Windowで、WindowStyleをNoneに設定し、ResizeModeをNoResizeに設定した場合(私と一緒に、一度でもサイズを変更できます)、AllowsTransparencyのチェックが外れていることを確認してください。ブラウザコントロール。

さて、おそらくまだ正しいサイズに変更したいですか?相互運用性の呼び出しでこれを実現できます。

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

ほら、境界線のないWPFウィンドウであり、WebBrowserのようなコントロールとの互換性を失うことなく、移動およびサイズ変更が可能です。


右下だけでなく、すべての側面からサイズを変更したいが、境界線を表示したくない場合はどうすればよいですか?
Daniel

6
以下に、他のwParam値を示します。必要に応じて、これらを使用して新しいイベントを新しいUIオブジェクトに割り当てますprivate enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, TopLeft = 61444, TopRight = 61445, Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, }
Wobbles

これは私にとってはうまくいきますが、1つの例外はありますが、NoResizeを取得すると、ウィンドウを上部にドラッグしてスナップすることができなくなります。
CJK 2015年

2
@CJK真ですが、そのためのWindowsメッセージをフックして処理できることは間違いありません。
2015年

ウィンドウをドラッグできません。なぜか?(リサイズはチャームのように機能します)
Li3ro、2015年

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.