Поверните и измените размер окна при перетаскивании - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь добиться небольшого «трюка» в окне WPF.

Поэтому у меня есть горизонтальное окно шириной 500 и высотой 30 с WindowStyle на None, поэтому я добавляю кнопку для перемещения окнас функцией DragMove ().

Эта часть работает хорошо.

Моя проблема в том, что когда я перемещаю окно рядом с границей экрана, я хочу повернуть окно, чтобы получитьпо вертикали 30x500 (это работает как время доктора уменьшило планку).

Для этого я слушаю событие LocationChanged.

Вот код:

XAML:

<Window x:Class="POCClient1.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"
        mc:Ignorable="d"
        Title="Echino Time"
        Height="30" Width="500"
        Topmost="True"
        WindowStyle="None"
        ResizeMode="NoResize"
        WindowStartupLocation="CenterScreen">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Close"
                        Executed="CloseCmdExecuted"
                        CanExecute="CloseCmdCanExecute"/>
    </Window.CommandBindings>
    <Grid x:Name="ContainerGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>

        <UniformGrid x:Name="ButtonUniformGrid2" Grid.Column="0" Columns="2" Rows="1" HorizontalAlignment="Stretch">
            <Button Grid.Column="0" x:Name="MoveButton" PreviewMouseLeftButtonDown="MoveWindow" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="3" Cursor="Hand">
                <Image Source="images/move.png" />
            </Button>
            <Button Grid.Column="0" x:Name="RotateButton" Click="RotateButton_Click" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="3">
                <Image Source="images/rotate.png" />
            </Button>
        </UniformGrid>

        <UniformGrid x:Name="ButtonUniformGrid" Grid.Column="1" Columns="2" Rows="1" HorizontalAlignment="Stretch">
            <Button Margin="3" Click="StartButton_Click">Start</Button>
            <Button Margin="3" Click="StopButton_Click">Stop</Button>
        </UniformGrid>

        <Label  Grid.Column="2" x:Name="TaskLabel" Content="POC 01" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="0" Margin="0,7" />
        <Label  Grid.Column="3" x:Name="TimeLabel" HorizontalAlignment="Left" VerticalAlignment="Center" Padding="0" Content="Chrono" />
        <Button Grid.Column="4" x:Name="CloseButton" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="3" Command="ApplicationCommands.Close">
            <Image Source="images/close.png" />
        </Button>
    </Grid>
</Window>

C #:

public partial class MainWindow : Window
    {
        private DispatcherTimer _dispatcherTimer;
        private Stopwatch _stopwatch = new Stopwatch();
        private enum Orientation { Horizontal, Vertical };
        private Orientation _windowOrientation;

        public MainWindow()
        {
            InitializeComponent();

            _windowOrientation = Orientation.Horizontal;
            _dispatcherTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(500)
            };
            _dispatcherTimer.Tick += DispatcherTimer_Tick;
            //LocationChanged += MainWindow_LocationChanged;
        }

        private void MainWindow_LocationChanged(object sender, EventArgs e)
        {
            // https://stackoverflow.com/questions/48399180/wpf-current-screen-dimensions
            System.Drawing.Rectangle workingArea = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(this).Handle).WorkingArea;

            if (_windowOrientation == Orientation.Horizontal && (Left < 0 || Left > (SystemParameters.VirtualScreenWidth - Width)))
            {
                RotateToVerticalWindow();
            }
            else if (_windowOrientation == Orientation.Vertical && (Top < 0 || Top < Height))
            {
                RotateToHorizontalWindow();
            }
        }

        private void CloseCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void CloseCmdExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            Close();
        }

        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            if (_stopwatch.IsRunning)
            {
                TimeLabel.Content = $"{_stopwatch.Elapsed:hh':'mm':'ss}";
            }
        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            _stopwatch.Start();
            _dispatcherTimer.Start();
        }

        private void StopButton_Click(object sender, RoutedEventArgs e)
        {
            _stopwatch.Stop();
            _dispatcherTimer.Stop();
        }

        private void RotateButton_Click(object sender, RoutedEventArgs e)
        {
            if (_windowOrientation == Orientation.Horizontal)
            {
                RotateToVerticalWindow();
            }
            else if (_windowOrientation == Orientation.Vertical)
            {
                RotateToHorizontalWindow();
            }
        }

        // Move the window with drag of the button. Ensure that we are not over the taskbar
        private void MoveWindow(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
            DragMove();

            // https://stackoverflow.com/questions/48399180/wpf-current-screen-dimensions
            System.Drawing.Rectangle workingArea = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(this).Handle).WorkingArea;

            //The left property of the window is calculated on the width of all screens, so use VirtualScreenWidth to have the correct width
            if (Top > (workingArea.Height - Height))
            {
                Top = (workingArea.Height - Height);
            }
            else if (Left > (SystemParameters.VirtualScreenWidth - Width))
            {
                Left = (SystemParameters.VirtualScreenWidth - Width);
            }
            else if (Left < 0)
            {
                Left = 0;
            }
        }

        private void RotateToVerticalWindow()
        {
            // Set new Width and Height for the window
            Width = 30;
            Height = 500;

            RotateTransform myRotateTransform = new RotateTransform
            {
                Angle = 90
            };

            ContainerGrid.LayoutTransform = myRotateTransform;
            _windowOrientation = Orientation.Vertical;
        }

        private void RotateToHorizontalWindow()
        {
            // Set new Width and Height for the window
            Width = 500;
            Height = 30;

            RotateTransform myRotateTransform = new RotateTransform
            {
                Angle = 0
            };

            ContainerGrid.LayoutTransform = myRotateTransform;
            _windowOrientation = Orientation.Horizontal;
        }
    }

Проблема в том, что когда я достигаю границы, содержимое окна поворачивается, но окно не принимает новый размер.

То, чего я хочу добиться, - это вращение окна и его содержимого, сохраняя при этом перетаскивание, чтобы мы могли продолжать перетаскивание после поворота.

Сейчас я добавляю кнопку, чтобы «вручную» вращать окночтобы увидеть эффект, и он работает нормально.

Thанки заранее :) 1025 *

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