我正在为客户开发一个应用程序,其中一个要求是能够进行约会,并以可视格式显示当前周的约会,就像在Google日历或Microsoft Office中一样。我在codeproject上发现了一篇很棒的(3部分)文章,其中他构建了一个“RangePanel”,并为每个“句点”(例如,工作日)组成一个。你可以在这里找到第1部分:
http://www.codeproject.com/KB/WPF/OutlookWpfCalendarPart1.aspx
代码显示,但似乎总体上选择任意高度值(440.04),并且不会在没有剪裁的情况下调整大小。我的意思是,窗口/容器将调整大小,但它只是切断控件的底部,而不是重新计算范围面板的高度,以及表示约会的范围面板中的控件。它会调整大小并重新计算更大的值,但不能更少。
代码方面,正在发生的事情是,当您调整大小低于该值时,首先使用正确的“新高度”调用MeasureOverride
。但是,在调用ArrangeOverride
方法时,它会传递与要安排的高度相同的440.04值。
我需要找到一个解决方案/解决方法,但是您可以提供的任何可能指导我查看的内容的信息也会非常感激(我理解当您没有这些时调试代码是多么令人沮丧)在你面前的代码库。:))
下面提供了各种排列和测量功能的代码。 CalendarView
控件有CalendarViewContentPresenter
,可处理多个句点。然后,句点有CalendarPeriodContentPresenter
,它处理约会的每个“块”。最后,RangePanel
有自己的实现。 (老实说,我对控件的工作方式仍然有点朦胧,所以如果我的解释有点模糊,我链接的文章可能会有更有说服力的解释。:))
CalendarViewContentPresenter :
protected override Size ArrangeOverride(Size finalSize)
{
int columnCount = this.CalendarView.Periods.Count;
Size columnSize = new Size(finalSize.Width / columnCount, finalSize.Height);
double elementX = 0;
foreach (UIElement element in this.visualChildren)
{
element.Arrange(new Rect(new Point(elementX, 0), columnSize));
elementX = elementX + columnSize.Width;
}
return finalSize;
}
protected override Size MeasureOverride(Size constraint)
{
this.GenerateVisualChildren();
this.GenerateListViewItemVisuals();
// If it's coming back infinity, just return some value.
if (constraint.Width == Double.PositiveInfinity)
constraint.Width = 10;
if (constraint.Height == Double.PositiveInfinity)
constraint.Height = 10;
return constraint;
}
CalendarViewPeriodPersenter :
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement element in this.visualChildren)
{
element.Arrange(new Rect(new Point(0, 0), finalSize));
}
return finalSize;
}
protected override Size MeasureOverride(Size constraint)
{
this.GenerateVisualChildren();
return constraint;
}
RangePanel :
protected override Size ArrangeOverride(Size finalSize)
{
double containerRange = (this.Maximum - this.Minimum);
foreach (UIElement element in this.Children)
{
double begin = (double)element.GetValue(RangePanel.BeginProperty);
double end = (double)element.GetValue(RangePanel.EndProperty);
double elementRange = end - begin;
Size size = new Size();
size.Width = (Orientation == Orientation.Vertical) ? finalSize.Width : elementRange / containerRange * finalSize.Width;
size.Height = (Orientation == Orientation.Vertical) ? elementRange / containerRange * finalSize.Height : finalSize.Height;
Point location = new Point();
location.X = (Orientation == Orientation.Vertical) ? 0 : (begin - this.Minimum) / containerRange * finalSize.Width;
location.Y = (Orientation == Orientation.Vertical) ? (begin - this.Minimum) / containerRange * finalSize.Height : 0;
element.Arrange(new Rect(location, size));
}
return finalSize;
}
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement element in this.Children)
{
element.Measure(availableSize);
}
// Constrain infinities
if (availableSize.Width == double.PositiveInfinity)
availableSize.Width = 10;
if (availableSize.Height == double.PositiveInfinity)
availableSize.Height = 10;
return availableSize;
}
答案 0 :(得分:1)
所以,今天早上经过多次打猎,我找到了一个解决方法。如果这提供了洞察力并且其他人找到了解决方案,我仍然会将您的标记视为已接受的解决方案,因为这对我来说似乎很苛刻。
基本上,今天早上,我拿出了众所周知的大棒,并决定看看如果我将MaxHeight设置为某个值(100)会发生什么,然后看看它会如何呈现。事实证明,它正确地控制了控制,并且看不到任何裁剪!所以,我想我会尝试将MaxHeight属性数据绑定到XAML中窗口的高度。这不起作用,所以我尝试从后面的代码中做到这一点,但仍然没有运气。所以,我回去验证这个现象,并再次将MaxHeight设置为100,并运行程序。它调整到窗口的大小,这是奇怪的,因为我没有把它设置为100?然后我意识到它将它设置为100,然后代码隐藏覆盖了该值,允许它向上扩展。调整窗口大小甚至具有所需的无剪裁效果......直到你达到100高度。所以,我将MaxHeight设置为零,这显然是在控件内部并打破了一些伪最小高度属性,然后窗口允许它扩展到它的全尺寸。
这是非常hacky,但它现在有效。 = /对我来说似乎很奇怪,我通过设置MaxHeight属性来启用缩小控件。 ><