WPF窗口比例如何保持恒定?

a7066163 2012-10-25 11:04:50
因工作需要调整一个软件的UI,需要做成像Media Center那样的窗口,就是拖放窗口时窗口的比例保持不变。比如16:9就一直是16:9。我现在遇到的问题是我在窗口的SizeChanged事件中写了如下代码

double preWidth = e.PreviousSize.Width;
double preHeight = e.PreviousSize.Height;

double curWidth = e.NewSize.Width;
double curHeight = e.NewSize.Height;

if (this.Height != preHeight)
{
 if (curHeight >= preHeight)
 {
 this.Width = curHeight * 1.713;
 }
 else if (curHeight < preHeight)
 {
 this.Width = curHeight * 1.713;
 }
}
else
{
 if (curWidth >= preWidth)
 {
 this.Height = curWidth / 1.713;
 }
 else if (curWidth < preWidth)
 {
 this.Height = curWidth / 1.713;
 }
}

让我困惑的是,这段代码在勾选”拖拉时显示窗口内容“时,拖拉表现不正常。鼠标在拖住不放的时候,窗口会变大,但是一旦释放鼠标左键,窗口又变回了原来的大小。如果不勾选 ”拖拉时显示窗口内容“,窗口拖拉正常,没有问题。

因为现在不能修改系统设置,但是又不想自定义窗口,所以只能在勾选 ”拖拉时显示窗口内容“的状态下实现拖拉窗口,并保持窗口比例恒定。请问我的代码有什么问题,或者说有别的方法可以实现?


我的开发环境:Windows 8预览版,VS2012 RC版
...全文
488 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
a7066163 2012-10-26
  • 打赏
  • 举报
回复
3L的方案给了我启发,虽然在在鼠标释放的慢的情况下,窗口会退回原来的大小,所以我只在处理鼠标释放的事件就行了。不过貌似自带边框的鼠标事件不属于窗口事件,最后我直接捕获WM_EXITSIZEMOVE消息,重载了窗口消息处理函数。通过定时器和WM_EXITSIZEMOVE消息处理的双重保证下,大致能实现窗口比例实时恒定的效果。
WM_EXITSIZEMOVE消息处理代码:

// 捕获窗口拖拉消息
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = HwndSource.FromVisual(this) as HwndSource;
if (source != null)
{
source.AddHook(new HwndSourceHook(WinProc));
}
}

public const Int32 WM_EXITSIZEMOVE = 0x0232;

// 重载窗口消息处理函数
private IntPtr WinProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, ref Boolean handled)
{
IntPtr result = IntPtr.Zero;
switch (msg)
{
// 处理窗口消息
case WM_EXITSIZEMOVE:
{
// 上下拖拉窗口
if (this.Height != LastHeight)
{
this.Width = this.Height * 1.713;
}
else // 左右拖拉窗口
{
this.Height = this.Width / 1.713;
}

LastWidth = (int)this.Width;
LastHeight = (int)this.Height;
break;
}
}

return result;
}
再次感谢3L的朋友!!!
a7066163 2012-10-25
  • 打赏
  • 举报
回复
主要是不能修改系统设置,默认是勾选“拖拉时显示窗口内容”,所以要在勾选的状态下
andy1020tc 2012-10-25
  • 打赏
  • 举报
回复
对2012不熟悉 不过不勾选“拖拉时显示窗口内容”不行吗?
不太明白为什么非要勾选那个
a7066163 2012-10-25
  • 打赏
  • 举报
回复
忘记谢谢3L了哈
a7066163 2012-10-25
  • 打赏
  • 举报
回复
延迟了之后确实好了不少,但是一旦鼠标释放的慢,还是会出现退回原来大小的情况,解决不了根本问题。
Hauk 2012-10-25
  • 打赏
  • 举报
回复
拖拉时显示窗口内容 不勾选时:一次拖动只触发一次SizeChanged事件
拖拉时显示窗口内容 勾选时:一次拖动只触发 N 次SizeChanged事件(n=newsize-oldsize)

触发太频繁所以界面更新有点不对劲。
可以使用timer来延迟更新,等用户拖好了来.


private Timer timer;
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (timer != null)
timer.Dispose();

timer = new Timer(setSize, e, 200, 200);
}

private void setSize(object eo)
{
SizeChangedEventArgs e = eo as SizeChangedEventArgs;
if (e.WidthChanged)
{
if (e.NewSize.Height != e.NewSize.Width / 2.0)
{
this.Dispatcher.BeginInvoke(new Action(() => { this.Height = e.NewSize.Width / 2.0; }));
}
}
else if (e.HeightChanged)
{
if (e.NewSize.Width != e.NewSize.Height * 2.0)
{
this.Dispatcher.BeginInvoke(new Action(() => { this.Width = e.NewSize.Height * 2.0; }));
}
}
timer.Dispose();
}

111,093

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧