# Validation

## Content



GanttView not only facilitates you to create project schedules, but also helps you in keeping your project data consistent. It does so by prohibiting invalid data entries or modifications to avoid conflicts. For instance, it prevents cyclic connection between tasks to avoid illogical task relationships. Here, a cyclic connection refers to a connection that occurs when the successor task and the predecessor task are the same for a given task.

The following GIF shows how GanttView prohibits the user to create a cyclic connection between tasks.

![](https://cdn.mescius.io/document-site-files/images/14a478dc-2b0f-437a-969b-b17e430e375e/images/task-validation.gif)

To avoid cyclic connection in GanttView, follow the given steps:

1.  Create a method, say **FindCyclicTasks()**, to find cyclic connections in GanttView. Here, we used the **Intersect** method to check if a task has same predecessor and successor.
    
    ```csharp
    public static class Extensions
    {
        public static IEnumerable<Task> FindCyclicTasks(this Task task)
        {
            return task.Predecessors.Select(x => x.PredecessorTask).Intersect(task.Successors);
        }
    }
    ```
    
2.  Create **ListChanged** event of the <span data-popup-content="This class is available in \u003ca href=\u0022/componentone/api/wpf/online-ganttview/dotnet-api/C1.WPF.GanttView/C1.GanttView.TaskCollection.html\u0022\u003e.NET\u003c/a\u003e and \u003ca href=\u0022/componentone/api/wpf/online-ganttview/dotnet-api/C1.WPF.GanttView/C1.GanttView.TaskCollection.html\u0022\u003e.NET Framework\u003c/a\u003e." data-popup-title="TaskCollection" data-popup-theme="ui-tooltip-green qtip-green">TaskCollection</span> class and subscribe to it. This event gets fired when the task list changes at runtime.
    
    ```csharp
    gv.Tasks.ListChanged += OnListChanged;
    ```
    
3.  Add the following code to the ListChanged event handler. This code checks for any cyclic connection within the project's schedule and clears it.
    
    ```csharp
    private void OnListChanged(object? sender, System.ComponentModel.ListChangedEventArgs e)
    {
        foreach (Task task in gv.Tasks)
        {
            if (task.Initialized)
            {
                // find cyclic tasks
                var cyclicTasks = task.FindCyclicTasks();
                if (cyclicTasks.Any())
                {
                    // clear cylcic tasks
                    var predecessors = task.Predecessors.Join(cyclicTasks,
                        predecessor => predecessor.PredecessorTaskID, 
                        successor => successor.ID, (predecessor, successor) => predecessor).ToList();
                    foreach (var predecessor in predecessors)
                        task.Predecessors.Remove(predecessor);
                }
            }
        }
    }
    ```