Skip to main content

ComponentOne (C1.WPF) Usage Guide

This document describes the usage patterns, performance optimization, and theme integration of ComponentOne WPF components in GST projects. Applicable to ProcessVision and Jope-PLC-Monitor.

1. Components Used

PackageVersionPurpose
C1.WPF.Core8.0.20242.966Core components
C1.WPF.Chart8.0.20242.966FlexChart charting
C1.WPF.Grid8.0.20242.966FlexGrid data grid
C1.WPF.Input8.0.20242.966Input controls
C1.WPF.DateTimeEditors8.0.20242.966Date/time pickers
C1.WPF.Gauge8.0.20242.966Gauge dashboard
C1.WPF.Themes.Material8.0.20242.966Material theme
C1.WPF.Themes.MaterialDark8.0.20242.966Material Dark theme

2. FlexChart Real-Time Charts

2.1 XAML Definition

xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"

<c1:FlexChart x:Name="dataChart"
ChartType="Line"
LegendPosition="Bottom"
ToolTipContent="{}{seriesName}&#x0a;Time: {x:HH:mm:ss}&#x0a;Value: {y:F2}">
<c1:FlexChart.AxisX>
<c1:Axis Title="Time" Format="HH:mm:ss" LabelAngle="-45" MajorGrid="True">
<c1:Axis.MajorGridStyle>
<c1:ChartStyle Stroke="#3A3A3A" />
</c1:Axis.MajorGridStyle>
</c1:Axis>
</c1:FlexChart.AxisX>
<c1:FlexChart.AxisY>
<c1:Axis Title="Value" MajorGrid="True">
<c1:Axis.MajorGridStyle>
<c1:ChartStyle Stroke="#3A3A3A" />
</c1:Axis.MajorGridStyle>
</c1:Axis>
</c1:FlexChart.AxisY>
</c1:FlexChart>

2.2 Building Series in Code

private void BuildChartSeries()
{
dataChart.BeginUpdate(); // 暫停渲染
try
{
dataChart.Series.Clear();

var colors = new[]
{
Color.FromRgb(0xFF, 0x57, 0x22), // Deep Orange
Color.FromRgb(0x3F, 0x51, 0xB5), // Indigo
Color.FromRgb(0x4C, 0xAF, 0x50), // Green
Color.FromRgb(0x9C, 0x27, 0xB0), // Purple
Color.FromRgb(0x00, 0xBC, 0xD4), // Cyan
Color.FromRgb(0xFF, 0xC1, 0x07), // Amber
Color.FromRgb(0xE9, 0x1E, 0x63), // Pink
Color.FromRgb(0x60, 0x7D, 0x8B) // Blue Grey
};

int colorIndex = 0;
foreach (var dataSeries in _viewModel.DataSeries)
{
if (!dataSeries.IsVisible || dataSeries.DataPoints.Count == 0)
continue;

var brush = new SolidColorBrush(colors[colorIndex % colors.Length]);
brush.Freeze(); // 記憶體最佳化

var series = new Series
{
SeriesName = dataSeries.DisplayName,
ItemsSource = dataSeries.DataPoints,
Binding = "Value",
BindingX = "Timestamp",
Style = new ChartStyle
{
Stroke = brush,
StrokeThickness = 2
}
};

dataChart.Series.Add(series);
colorIndex++;
}
}
finally
{
dataChart.EndUpdate(); // 恢復渲染
}
}

2.3 Data Model

public class ChartDataPoint
{
public DateTime Timestamp { get; set; }
public double Value { get; set; }
}

The Series Binding maps to the Value property, and BindingX maps to the Timestamp property.

2.4 Real-Time Update (Incremental Refresh)

private void RefreshChartData()
{
dataChart.BeginUpdate();
try
{
var selectedTags = _viewModel.SelectedTags;
for (int i = 0; i < dataChart.Series.Count && i < selectedTags.Count; i++)
{
// 只更新 ItemsSource,不重建 Series
dataChart.Series[i].ItemsSource = selectedTags[i].GetPoints();
}
}
finally
{
dataChart.EndUpdate();
}
}

Key point: Do not rebuild Series on every polling cycle — only update ItemsSource.

3. Performance Optimization

3.1 BeginUpdate / EndUpdate

chart.BeginUpdate();    // 暫停所有渲染
try
{
// 批量操作(加/移 Series、更新 ItemsSource)
}
finally
{
chart.EndUpdate(); // 一次性渲染
}

Must be used. Without it, every Series.Add() or ItemsSource change triggers a redraw, causing UI lag with large datasets.

3.2 Brush Freezing

var brush = new SolidColorBrush(color);
brush.Freeze(); // 建立不可變副本,減少記憶體

Call Freeze() on reusable Brushes to prevent WPF from tracking changes.

3.3 Event-Driven Updates

// ViewModel 端
_viewModel.DataPointsUpdated += (s, e) => RefreshChartData();

// 不要在 Polling 迴圈中直接操作 Chart
// 透過事件解耦,由 UI 層決定更新時機

3.4 Large Dataset Recommendations

Data VolumeRecommendation
< 1,000 pointsDirect binding, no special handling needed
1,000 - 10,000 pointsUse BeginUpdate/EndUpdate
> 10,000 pointsConsider downsampling before binding

4. Theme Integration

4.1 Supported Themes

ThemeTypeUse Case
C1ThemeMaterialDarkDarkIndustrial monitoring (default)
C1ThemeMaterialLightGeneral office
C1ThemeSystemSystemFollows Windows settings
C1ThemeOffice365WhiteOfficeDocument processing

4.2 Applying a Theme

// ThemeHelper.cs
var theme = ThemeFactories[themeName]();
_currentThemeResources = theme.ThemeResources;

if (_currentThemeResources != null)
{
app.Resources.MergedDictionaries.Insert(0, _currentThemeResources);
}

4.3 Custom Palette

Resources/Themes/
├── DarkPalette.xaml ← Dark theme palette
└── LightPalette.xaml ← Light theme palette

Chart background colors, grid lines, and text colors are managed uniformly through the Palette, ensuring consistency with the overall theme.

5. ToolTip Format

ToolTipContent="{}{seriesName}&#x0a;Time: {x:HH:mm:ss}&#x0a;Value: {y:F2}"
SyntaxDescription
{seriesName}Series name
{x:format}X-axis value (supports DateTime format)
{y:format}Y-axis value (supports numeric format)
{value:format}Same as {y}
&#x0a;Newline (XML escaped)

6. License Management

Currently, neither project explicitly calls C1License.SetLicenseKey(), relying on the implicit licensing mechanism of the NuGet packages.

Notes for deployment:

  • Confirm that the ComponentOne license covers the deployment environment
  • .NET Reactor protection does not affect C1 license verification (C1 DLLs are not within the protection scope)

7. Development Guidelines

7.1 Series Management

  • Build Series in code-behind, not statically defined in XAML (because the number of Series changes dynamically)
  • Use a predefined color array + index assignment to ensure visual consistency
  • Provide empty state handling (display a prompt message when there is no data)

7.2 Performance

  • Always wrap batch operations with BeginUpdate/EndUpdate
  • Brush.Freeze() to reduce WPF tracking overhead
  • Notify UI of polling data via events; do not directly manipulate Chart in the polling loop

7.3 Themes

  • All Chart grid lines and background colors should use Palette Resources
  • Do not hardcode color values (except for the Series color array)
ProjectC1 UsageDescription
ProcessVisionFlexChart (historical data charts)Temperature/pressure trends, Data Chart Window
PLC-MonitorFlexChart (real-time trends) + FlexGridMulti-tag real-time monitoring, Alarm Grid

Document Version: v1.0 | Created: 2026-03-16 | Related Issue: GST-171