PertChartView

for WPF & .NET 4+ / .NET Core 3.1 / .NET 5+ and Silverlight™ 4+
New: WPF .NET Core/.NET 5+ support: with NuGet!

Demo source code NuGet package Reference

PertChartView component displays tasks events using a PERT diagram. Supports rearranging items using drag and drop operations, computing events based on items displayed by existing GanttChartDataGrid component instances, and custom element templates.

Screenshot
  • WPF +
    C#
  • WPF +
    Visual Basic®
  • Silverlight™ +
    C#
  • Silverlight™ +
    Visual Basic®
  •  Copy<pdpcc:PertChartView x:Name="PertChartView"></pdpcc:PertChartView>
                                                markup (xaml)
     Copyvar items = new ObservableCollection<PertChartItem>
    {
        new PertChartItem { DisplayedText = "A", Content = "Task event 1",},
        new PertChartItem { DisplayedText = "B", Content = "Task event 2",},};
    items[1].Predecessors.Add(new PredecessorItem { Item = items[0],});
    …
    PertChartView.Items = items;
                                                csharp
    Demo
  •  Copy<pdpcc:PertChartView x:Name="PertChartView"></pdpcc:PertChartView>
                                                markup (xaml)
     CopyDim items = New ObservableCollection(Of PertChartItem) From { _
        New PertChartItem With { .DisplayedText = "A", .Content = "Task event 1",}, _
        New PertChartItem With { .DisplayedText = "B", .Content = "Task event 2",}, _
        … _
    }
    items(1).Predecessors.Add(New PredecessorItem With { .Item = items(0),})
    …
    PertChartView.Items = items
    …
                                                csharp
  •  Copy<pdpcc:PertChartView x:Name="PertChartView"></pdpcc:PertChartView>
                                                markup (xaml)
     Copyvar items = new ObservableCollection<PertChartItem>
    {
        new PertChartItem { DisplayedText = "A", Content = "Task event 1",},
        new PertChartItem { DisplayedText = "B", Content = "Task event 2",},};
    items[1].Predecessors.Add(new PredecessorItem { Item = items[0],});
    …
    PertChartView.Items = items;
                                                csharp
    Demo
  •  Copy<pdpcc:PertChartView x:Name="PertChartView"></pdpcc:PertChartView>
                                                markup (xaml)
     CopyDim items = New ObservableCollection(Of PertChartItem) From { _
        New PertChartItem With { .DisplayedText = "A", .Content = "Task event 1",}, _
        New PertChartItem With { .DisplayedText = "B", .Content = "Task event 2",}, _
        … _
    }
    items(1).Predecessors.Add(New PredecessorItem With { .Item = items(0),})
    …
    PertChartView.Items = items
    …
                                                csharp

Items collection

To load and present data with PertChartView control, initialize the Items collection of the component, setting up PertChartItem objects representing task events identified by these main properties: DisplayedText, Content, and Predecessors. Predecessors collection (objects of type PredecessorItem) represents event transitions (tasks) and are identified by these properties: Item, DisplayedText, Content, and Effort.

DisplayedText values should be short entity identifiers, while Content and Effort values are displayed as chart element tool tips.

End users may use drag and drop operations to update shape positioning, if needed, in order to make the diagram fitting better to their own needs. You may also easily position items in code, setting their DisplayedRowIndex and DisplayedColumnIndex property values considering a virtual grid as the container of the elements.

You may set an ID or GUID for any item object as Key and GlobalKey property values, useful when mapping to relational data storage access layers. A generic Tag property is also available to support miscellaneous object linking scenarios. Note that you can also prepare items for PertChartView component from a GanttChartDataGrid instance using GetPertChartItems method.

 Copyvar items = GanttChartDataGrid.GetPertChartItems();
PertChartView.Items = items;
                        

Data binding

Although we designed the component to support items of specific types only (PertChartItem) to ensure high runtime performance, you may use our built-in collection converter (TaskEventItemsConverter) to set up data binding to custom collection types with ease. Alternatively, you can use a fully custom converter to provide collection synchronization upon your own needs.

The component is persistence layer independent, so you can bind it to data collections from virtually any data source, including but not limited to SQL Server® databases.

To be notified when items managed by the component change, simply handle the ItemCollectionChanged and ItemPropertyChanged events.

  • WPF
  • Silverlight™

Appearance

You may fully customize item appearance, either for the entire chart or for individual entries in the view, using attached properties such as PertChartView.ShapeFill, ShapeStroke, TextForeground, etc.

The component offers built-in critical path enumeration algorithms for task events and for event transitions (tasks themselseves), and you can use the appearance settings to highlight them according to your requirements.

And when you need to develop advanced features in your application, chart shapes may be fully redesigned using XAML based template for TaskEventTemplate property of the component.

Sometimes however, especially when integrating the component with a Gantt Chart control instance and need to use auto-generated items, you may want less cluttered output. You can find miscellaneous ways to optimize data such as by grouping more predecessor items (tasks between events) between the same two PERT Chart items (events) and display them as multiple vertically distributed dependency lines in the user. A few lines of custom code will do the magic.

Multi-tasks per line demo
Screenshot

Printing and image exporting

The component offers a Print method that may be called to initiate a direct print operation for its content. A custom PrintingTemplate definition that you can specify using XAML is repeatedly used when generating the printed pages.

Moreover, you can export scalable images of the component content by calling GetBitmapSource method on the fly. For example, you may then encode an output image to an external file format such as PNG, include the image into an element displayed in a custom printed document, or simply displaying it as read only content on the screen.

 CopyPertChartView.Print("Sample Document");
                        
 CopyPertChartView.Export((Action)delegate
{
    SaveFileDialog saveFileDialog = 
        new SaveFileDialog { Title = "Export Image To", Filter = "PNG image files|*.png" };
    if (saveFileDialog.ShowDialog() != true)
        return;
    BitmapSource bitmapSource = PertChartView.GetExportBitmapSource(96 * 2);
    using (Stream stream = saveFileDialog.OpenFile())
    {
        PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
        pngBitmapEncoder.Frames.Add(BitmapFrame.Create(bitmapSource));
        pngBitmapEncoder.Save(stream);
    }
});
                        

Windows® Forms

You may use the WPF component in Windows® Forms applications using Microsoft® ElementHost control from WindowsFormsIntegration assembly of .NET 4+.

Optionally, you can define a XAML user control in your Windows® Forms project to serve for encapsulation.

 Copyvar items =;
var host = new ElementHost 
{ 
    Child = new PertChartView
    { 
        Items = items,}, 
    Dock = DockStyle.Fill 
};
Controls.Add(host);