изменение размера окна при расширении элемента управления - PullRequest
2 голосов
/ 19 апреля 2011

получено из решения моей первоначальной задачи здесь

У меня теперь есть следующий xaml:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="300" Width="450" SizeToContent="WidthAndHeight">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="auto" />
        </Grid.ColumnDefinitions>
        <TabControl Grid.Column="0" MinWidth="200" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />       
        <Expander Grid.Column="1" Grid.Row="0" ExpandDirection="Right">
            <StackPanel x:Name="cont">
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
                <Label>testtesttesttesttest</Label>
            </StackPanel>
        </Expander>
    </Grid>
</Window>

Я хочу увеличивать ширину окна каждый раз, когда расширяю регулятор расширения вправо. Когда я запускаю приведенный выше xaml и раскрываю элемент управления экспандером после сборки, все работает как ожидалось, но как только я вручную изменю размер окна, содержимое элемента управления экспандера расширится в существующую область слева.

как я могу изменить это поведение, чтобы окно расширилось по ширине в правую сторону и содержимое оказалось в этой новой области?

1 Ответ

2 голосов
/ 19 апреля 2011

Это не то, что встроено в WPF, поэтому вам придется написать собственный код для его обработки. SizeToContent работает до тех пор, пока конечный пользователь не изменит размер окна, тогда размер окна будет фиксированным.

Вы можете использовать что-то подобное для достижения желаемого:

public partial class MainWindow  {
    public MainWindow() {
        InitializeComponent();
    }

    protected override void OnSourceInitialized(EventArgs e) {
        base.OnSourceInitialized(e);

        IntPtr handle = new WindowInteropHelper(this).Handle;
        HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(this.WindowProc));
    }

    private const int WM_SIZING = 0x0214;
    private const int WM_EXITSIZEMOVE = 0x0232;
    private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
        switch (msg) {
            case WM_SIZING:
                this.firstColumn.ClearValue(ColumnDefinition.MinWidthProperty);
                break;
            case WM_EXITSIZEMOVE:
                this.firstColumn.MinWidth = this.firstColumn.ActualWidth;
                this.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
                break;
        }

        return IntPtr.Zero;
    }

}

Тогда вам нужно дать вашему первому ColumnDefinition имя "firstColumn", например так:

<ColumnDefinition x:Name="firstColumn" Width="*" />

Так эффективно, он использует SizeToContent, как у вас. Если вы измените размер окна, он гарантирует, что минимальный размер первого столбца сохранит размер фиксированным, и снова включит SizeToContent.

EDIT:

Заметил, что вы использовали тег VB.NET, поэтому вот версия VB.NET:

Public Partial Class MainWindow
    Public Sub New()
        InitializeComponent()
    End Sub

    Protected Overrides Sub OnSourceInitialized(e As EventArgs)
        MyBase.OnSourceInitialized(e)

        Dim handle As IntPtr = New WindowInteropHelper(Me).Handle
        HwndSource.FromHwnd(handle).AddHook(New HwndSourceHook(AddressOf Me.WindowProc))
    End Sub

    Private Const WM_SIZING As Integer = &H214
    Private Const WM_EXITSIZEMOVE As Integer = &H232
    Private Function WindowProc(hwnd As IntPtr, msg As Integer, wParam As IntPtr, lParam As IntPtr, ByRef handled As Boolean) As IntPtr
        Select Case msg
            Case WM_SIZING
                Me.firstColumn.ClearValue(ColumnDefinition.MinWidthProperty)
                Exit Select
            Case WM_EXITSIZEMOVE
                Me.firstColumn.MinWidth = Me.firstColumn.ActualWidth
                Me.SizeToContent = System.Windows.SizeToContent.WidthAndHeight
                Exit Select
        End Select

        Return IntPtr.Zero
    End Function

End Class
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...