拖动时旋转并调整窗口大小

时间:2018-09-26 13:36:35

标签: c# wpf

我尝试在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;
        }
    }

问题是,当我到达边框时,窗口的内容会旋转,但窗口不会采用新的尺寸。

我想实现的是旋转窗口及其内容,同时保持拖动处于活动状态,以便我们可以在旋转后继续拖动。

现在,我添加一个按钮来“手动”旋转窗口以查看效果,并且效果很好。

预先感谢:)

0 个答案:

没有答案