固定初始大小的可调整大小的WPF窗口
我编写了一个程序来可视化键盘的状态。当我调整窗口大小时,绘制矩形的画布保持其大小,但我希望将其调整为窗口大小。我试图为窗口和画布添加一个SizeChanged
事件处理程序,但那不起作用。固定初始大小的可调整大小的WPF窗口
我也尝试在窗口的SizeChanged
事件中设置Lights
画布的大小,但窗口在启动时几乎填满了整个屏幕。
那么我怎样才能达到以下目标?
- 最初,窗口的客户区是256×256。
- 窗口是可调整大小。
- 窗口大小调整后,其内容会随之缩放。
MainWindow.xaml
<Window x:Class="KeyMonitor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Key Monitor" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen" ResizeMode="CanResize">
<Grid>
<Canvas x:Name="Lights" Width="256" Height="256" />
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace KeyMonitor
{
public partial class MainWindow : Window
{
private Rectangle[] indicators = new Rectangle[256];
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 256; i++)
Lights.Children.Add(indicators[i] = new Rectangle { Fill = Brushes.Transparent });
Lights.SizeChanged += Lights_SizeChanged;
var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
timer.Tick += Timer_Tick;
timer.Start();
}
private void Lights_SizeChanged(object sender, SizeChangedEventArgs e)
{
//Lights.Width = e.NewSize.Width;
//Lights.Height = e.NewSize.Height;
for (int y = 0; y < 16; y++)
{
var sy = (int)(e.NewSize.Height * y/16);
var sy1 = (int)(e.NewSize.Height * (y + 1)/16);
for (int x = 0; x < 16; x++)
{
var sx = (int)(e.NewSize.Width * x/16);
var sx1 = (int)(e.NewSize.Width * (x + 1)/16);
var indicator = indicators[16 * y + x];
indicator.Width = 1 + sx1 - sx;
indicator.Height = 1 + sy1 - sy;
Canvas.SetLeft(indicator, sx);
Canvas.SetTop(indicator, sy);
}
}
}
void Timer_Tick(object sender, EventArgs e)
{
var keys = new byte[256];
if (User32.GetKeyboardState(keys) != 0)
{
for (int i = 0; i < 256; i++)
{
var r = (byte)((keys[i] & 0x7E) != 0 ? 0xFF : 0x00);
var g = (byte)((keys[i] & 0x01) != 0 ? 0xFF : 0x00);
var b = (byte)((keys[i] & 0x80) != 0 ? 0xFF : 0x00);
indicators[i].Fill = new SolidColorBrush(Color.FromRgb(r, g, b));
}
}
}
}
static class User32
{
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] lpKeyState);
}
}
我将设置Window
的尺寸为初始256 * 256,让Canvas
拉伸其中:
<Window x:Class="KeyMonitor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Key Monitor" Width="256" Height="256"
WindowStartupLocation="CenterScreen" >
<!-- Grid is not necessary-->
<Canvas x:Name="Lights" />
</Window>
HorizointalAlignment
和VerticalAlignment
的默认值为Stretch
,因此不需要设置其他属性。
默认的调整大小模式已经是CanResize
,所以它不是必需的。此外,我删除SizeToContent
值,因为默认值为Manual
,这是您在此处需要的值。
编辑:我发现一个初始大小的问题。在xaml中设置Width
和Height
表示包含Windows添加的边框的大小。所以如果Height=Width
的内容大小不是一个正方形。
我在SO上发现了一个解决方案:How to set WPF window's startup ClientSize?。这是不是最好的总是使用代码背后,但我认为这是一个合理的解决方法。这只是初始大小。
要缩放内容,请将画布置于视图框内。这将适当地缩放内容。
<ViewBox>
<Canvas x:Name="Lights" />
</ViewBox>
这很好地解决了我的一半问题,即调整画布大小。但它不能解决初始窗口大小。初始窗口大约填满了一半的屏幕,而不是256×256的区域。 –
这几乎就是我想要的。唯一缺少的是窗口_client area_的初始大小。奇怪的是,在Visual Studio设计器中,包含标题栏和边框的窗口为256×256,但是当我运行该应用程序时,该窗口仅为242×249. –
@RolandIllig您说得对,我能够重现此问题。我花了一点研究,并找到另一个SO线程的工作解决方案。我在我的答案中将其链接到它。 – Koopakiller
@RolandIllig你可以设置内容大小_and_使用'SizeToContent'属性。 – heltonbiker