c# - 通过在代码中设置高度和宽度来缩小视图大小不会正确更新
问题描述
在我的应用程序中,我们有一个包含许多嵌套视图的视图,以提供一些常见的功能,即:
在这种情况下:
一个带有 * 大小的主内容网格单元格和一个固定宽度的单元格的 ErrorPanelView (UserControl),其中包含一个验证消息面板(如果任何验证失败) - 此面板具有固定宽度,并且根据需要可见或折叠。
主要内容再次包含一个 ButtonPanelView,其中包含一个 * 大小的内容网格单元格和一个固定高度的单元格,其中包含标准按钮(确定、取消等)
主要内容然后保存“实际”视图 - 这可能有一个 min/maxHeight 和 min/maxWidth,对于这个例子,min/max 值是相同的,所以大小是静态的。
当视图出现验证错误时,validationPanel 变为可见。整体视图将按预期调整大小(宽度扩展),到目前为止一切都很好。但是,当用户处理验证错误时,验证面板应该消失,并且窗口应该缩小到其原始大小。确实发生的是内部视图将正确调整大小(至少看起来如此),但外部视图(ErrorPanelView 用户控件)将保持其更大的尺寸,并在验证面板之前可见的地方留下一个黑色区域。
用户单击用户控件的那一刻,用户控件将捕捉到其预期的(原始)大小。
我无法弄清楚我在这里缺少什么。
据我所知,尺寸计算正确,用户控件的高度和宽度设置为正确的值,但是序列有问题吗?- 或者我应该明确地调用一些系统事件?
还是完全不同的东西?
我难住了。
private static void CalculateWindowSize(BaseWindow window, List<View> views, bool adjustCurrentSize)
{
// Calculate the extra space the window consumes.
View topView = views.First();
double heightDiff = window.ActualHeight - topView.ActualHeight;
double widthDiff = window.ActualWidth - topView.ActualWidth;
double ww = window.Width; //
double tvw = topView.Width;
const double zeroTolerance = 0.6;
double maxHeightMax = 0, maxWidthMax = 0;
double maxHeightSum = 0, maxWidthSum = 0;
double minHeightMax = 0, minWidthMax = 0;
double minHeightSum = 0, minWidthSum = 0;
double heightSum = 0, widthSum = 0;
double heightMax = 0, widthMax = 0;
foreach (View view in views)
{
ViewSizeBehaviour viewHeightBehaviour = GetHeightSizeBehaviour(view);
ViewSizeBehaviour viewWidthBehaviour = GetWidthSizeBehaviour(view);
switch (viewHeightBehaviour)
{
case ViewSizeBehaviour.Sum:
{
if (!double.IsInfinity(view.MaxHeight)) maxHeightSum += view.MaxHeight;
if (Math.Abs(view.MinHeight) > zeroTolerance) minHeightSum += view.MinHeight;
// Default to MinHeight if WindowHeight not defined
if (!double.IsNaN(view.WindowHeight)) heightSum += view.WindowHeight;
else heightSum += view.MinHeight;
break;
}
case ViewSizeBehaviour.Max:
{
if (!double.IsInfinity(view.MaxHeight)) maxHeightMax = Math.Max(maxHeightMax, view.MaxHeight);
if (Math.Abs(view.MinHeight) > zeroTolerance) minHeightMax = Math.Max(minHeightMax, view.MinHeight);
// Default to MinHeight if WindowHeight not defined
heightMax = Math.Max(heightMax, !double.IsNaN(view.WindowHeight) ? view.WindowHeight : view.MinHeight);
break;
}
}
switch (viewWidthBehaviour)
{
case ViewSizeBehaviour.Sum:
{
if (!double.IsInfinity(view.MaxWidth)) maxWidthSum += view.MaxWidth;
if (Math.Abs(view.MinWidth) > zeroTolerance) minWidthSum += view.MinWidth;
// Default to MinWidth if WindowWidth not defined
if (!double.IsNaN(view.WindowWidth)) widthSum += view.WindowWidth;
else widthSum += view.MinWidth;
break;
}
case ViewSizeBehaviour.Max:
{
if (!double.IsInfinity(view.MaxWidth)) maxWidthMax = Math.Max(maxWidthMax, view.MaxHeight);
if (Math.Abs(view.MinWidth) > zeroTolerance) minWidthMax = Math.Max(minWidthMax, view.MinWidth);
// Default to MinWidth if WindowWidth not defined
widthMax = Math.Max(widthMax, !double.IsNaN(view.WindowWidth) ? view.WindowWidth : view.MinWidth);
break;
}
}
}
if (adjustCurrentSize)
{
window.Height = Math.Max(heightSum, heightMax) + heightDiff;
window.Width = Math.Max(widthSum, widthMax) + widthDiff;
}
// Only set maximum height & width if they are greater than zero. Otherwise all views have specified Infinity as max height
double maxHeight = Math.Max(maxHeightSum, maxHeightMax);
double maxWidth = Math.Max(maxWidthSum, maxWidthMax);
if (Math.Abs(maxHeight) > zeroTolerance)
{
window.MaxHeight = maxHeight + heightDiff;
if (window.MaxHeight < window.Height || window.MaxHeight < window.ActualHeight)
{
window.Height = window.MaxHeight;
}
}
if (Math.Abs(maxWidth) > zeroTolerance)
{
window.MaxWidth = maxWidth + widthDiff;
if (window.MaxWidth < window.Width || window.MaxWidth < window.ActualWidth)
{
window.Width = window.MaxWidth;
}
}
// Minimum height & width are the maximum of either the sum or max calculations
window.MinHeight = Math.Max(minHeightSum, minHeightMax) + heightDiff;
window.MinWidth = Math.Max(minWidthSum, minWidthMax) + widthDiff;
解决方案
问题上的标签说WPF
and XAML
,但代码是这样写的,这是一个 winforms 应用程序,所以我不是 100% 确定如何回答这个问题。
我将假设标签是正确的并且您是 WPF 的新手。
基本上,您问题中的所有代码在 WPF 应用程序中都不需要。WPF 相对于 Winforms 的主要优势之一是内容的自动调整大小;Winforms 没有为您做的事情。
在 WPF 中,您在 UserControl 中设置 XAML,以便当您遇到错误情况时,验证错误 UserControl 变为 Visibile。您只需将布尔属性绑定到Visibility
UserControl 的属性(也使用 ValueConverter),然后在处理错误时,布尔值设置为 false 并且验证 UserControl 消失,WPF 会自动调整其余内容的大小。您无需编写任何代码来调整大小(这是旧的 Winforms 方式)。
当然,在 XAML 中需要学习很多东西来设置您的 UserControl,以便自动调整大小以您希望的方式发生,但是不再需要编写包含所有数学和计算和重绘的繁琐代码。
希望这能让你指出正确的方向。有大量的教程和帮助可以在 XAML 中设置 UserControls 并将布尔属性绑定到控件上的 Visibility 属性以及使用 IValueConverters。
推荐阅读
- google-apps-script - 将变量从一个 html 页面传递到另一个 html 页面
- leaflet - 传单:如何缩放以保持固定位置?
- django - Django,get和filter查询集方法的属性
- ajax - 如何同时运行多个ajax请求
- vim - 如何对 EJS 文件使用 vim 自动完成功能
- python - Elastic Beanstalk - 命令“/opt/python/run/venv/bin/pip install -r /opt/python/ondeck/app/requirements.txt”返回非零退出状态 1
- swiftui - 使用 SwiftUI 显示错误
- typescript - 返回从数组参数中输入的键定义的选择类型的函数
- tensorflow - 如何为图像分类问题选择卷积神经网络中密集层的单元数?
- html - 你好,我的链接失效了。每次我尝试点击它们时,它都会提示一个错误,除了主页(索引)链接