【发布时间】:2018-03-02 13:45:24
【问题描述】:
我在使用 telerik:RadGanttView 控件时遇到了一些问题。我认为这是针对 WPF 的 Telerik 工具包 UI 特有的问题,但我会尽可能详细地解释该问题,以便其他人可以提出解决方法(如果他们能想到一个)。
TLDR;
GanttView 可以通过将每个重复作为子事件放置在单个父事件中来显示重复任务。现在我的项目要求我将这个重复的任务系列嵌套到另一个父事件容器中。
选择作为嵌套层次结构的一部分的重复任务事件(深度至少为2级)时,应用程序将抛出System.NullReferenceException和崩溃。
更具体地说,仅当所有父节点都折叠时才会发生此错误。如果只有顶部节点折叠,其他子节点仍然展开,则不会出现问题。
这是 System.NullReferenceException 的 StackTrace:
System.NullReferenceException 被捕获
在 System.Collections.Generic.Dictionary'2.Add(TKey key, TValue value)
在 Telerik.Windows.Rendering.VirtualizedGridPanel.Handler.SetArrangeRect(Int32 列,Int32 行,矩形矩形) 在 Telerik.Windows.Rendering.Internal.GridRenderingHelper.MeasureItemsCore(矩形视口,IGridContainersHandler 处理程序)
在 Telerik.Windows.Rendering.Internal.GridRenderingHelper.MeasureItems(矩形视口,IGridContainersHandler 处理程序)
在 Telerik.Windows.Rendering.VirtualizedGridPanel.MeasureContainers(IContainerRecycler recycler, Size availableSize)
在 Telerik.Windows.Rendering.Virtualization.VirtualizedPanel.MeasureOverrideCore(Size availableSize)
在 Telerik.Windows.Rendering.ScrollablePanel.MeasureOverride(Size availableSize)
在 System.Windows.FrameworkElement.MeasureCore(可用大小)
在 System.Windows.UIElement.Measure(可用大小)
在 Telerik.Windows.Controls.GanttPresenterPanel.MeasureContainer(UIElement 容器,尺寸 measureSize)
在 Telerik.Windows.Controls.GanttPresenterPanel.MeasureOverride(Size availableSize)
在 System.Windows.FrameworkElement.MeasureCore(Size availableSize)
详细说明:
我的代码基于RecurringTask_WPF example project。
我能够获得我想要的视觉结果,但我偶然发现了一个导致我的应用程序崩溃的操作。
这使得它几乎无法使用,所以我需要找到一个解决方案,或者至少找到一种方法来捕获异常并防止它崩溃。
我已经能够查明问题的原因,但我无法自己解决。
让我先描述一下我目前的情况/环境。
在默认的 RecurringTask_WPF 示例项目中,如果您折叠 “Recurrence Series”(父树节点),那么您可以看到每个重复任务旁边的所有子重复任务其他。
当您单击其中一个事件时,例如:"Recurrence 1" 块(在 RadGanttView 的 TimeRuler Part 中),然后选择此特定的重复任务。这会导致树节点自动展开并突出显示选定的任务/事件。
此行为按预期完美运行,我希望保持原样。
但是,一旦您将重复执行的任务嵌套到一个额外的层次结构中(这是我的要求),就会引发异常并且程序停止工作。
首先,我将为您提供更改示例项目以重现问题的代码。 (这也应该有助于进一步解释确切的问题)
您应该将 ViewModel.cs 的 GetTasks() 方法替换为以下代码:
private ObservableCollection<IGanttTask> GetTasks()
{
var collection = new ObservableCollection<IGanttTask>();
var today = DateTime.Today.AddHours(8);
var child1 = new RecurrenceTask(today, today.AddHours(4), "Recurrence 1");
var child2 = new RecurrenceTask(today.AddHours(0), today.AddHours(12), "Recurrence 2");
var child3 = new RecurrenceTask(today.AddHours(13), today.AddHours(20), "Recurrence 3");
var task2 = new RecurrenceTask(today.AddHours(13), today.AddHours(20), "Recurrence Series2")
{
Children = { child3 }
};
var task1 = new RecurrenceTask(today, today.AddHours(20), "Recurrence Series1")
{
Children = { child1, child2, task2 }
};
collection.Add(task1);
var taskWithoutRecurrence = new GanttTask(today.AddHours(8), today.AddHours(13), "Task Without Recurrence");
taskWithoutRecurrence.Children.Add(new GanttTask(today.AddHours(9), today.AddHours(12), "Child Task"));
collection.Add(taskWithoutRecurrence);
return collection;
}
当您通过这些代码更改运行此示例时,您应该会看到“Recurrence 3” 任务现在已移至新的“Recurrence Series2”。
这个新系列也是原“Recurrence Series1”的子系列。
因此,当所有节点都折叠时,您仍然可以看到所有子节点彼此相邻。
如果您现在单击 "Recurrence 3" 事件(在 RadGanttView 的 TimeRuler 部分),应用程序将抛出 System.NullReferenceException(上面的 StackTrace)。
以下是一些其他观察结果,可能会帮助您找到此问题的确切原因以及可能的解决方案/解决方法:
- 如果您要单击任何其他重复任务,则程序将继续按预期工作。
- 如果只有顶部节点折叠,因此子 "Recurrence Series2" 保持展开状态。然后,该行为也会继续按预期工作。
似乎只有当嵌套节点折叠并且选择了至少 2 层深的层次结构的子任务时才会出现问题。
我只想找到一种方法来阻止我的程序崩溃。
我已尝试处理单击事件以防止用户单击 RadGanttView 的 TimeRuler 部分中的事件,但我无法弄清楚如何正确执行此操作,我仍然想保留自动展开和选择点击任务的行为。
我也尝试过实现点击命令,这表明扩展实际上可以正常工作,并且仅在之后发生异常。
非常感谢任何帮助/建议。
【问题讨论】: