# Charts and Barcodes

> Insert QR codes and Code 128 barcodes with TXBarcodeControl and BarcodeFrame, update them, and add charts bound to a DataTable in Windows Forms documents.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Document Processing > Charts and Barcodes
- **4818 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/charts-barcodes/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/charts-barcodes/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/charts-barcodes/llms-full.txt

---

A QR code that links an invoice to a customer portal, a Code 128 barcode with an order number on a packing slip and a bar chart of the quarter's sales are frames that TX Text Control places in a document like images. In a Windows Forms application, your code creates them, positions them, changes their data later and removes them. Barcodes work with the NuGet package alone, while charts need the chart control of Windows Forms, which the last sections explain.

Users insert barcodes and charts from the ribbon, as described in [Charts and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/charts-barcodes/llms-full.txt), and [Integrating Charts and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/integration/charts-barcodes/llms-full.txt) covers the references and controls your project needs. Barcodes and charts that a mail merge fills with data are the subject of [Images and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/images-barcodes/llms-full.txt). Frames are positioned as [Images, Text Frames, and Shapes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/images-shapes/#how-frames-are-placed) describes. *Form1.cs* needs these `using` directives:

```csharp
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using TXTextControl;
using TXTextControl.Barcode;
using TXTextControl.DataVisualization;
```

The `System.Windows.Forms.DataVisualization.Charting` directive is needed only for charts.

### How Barcodes Work

A barcode in a document consists of two objects:

- **[TXBarcodeControl](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/llms-full.txt)** holds the barcode: its [BarcodeType](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/barcodetype/enumeration/llms-full.txt), the encoded text and its appearance. Despite its name, the Windows Forms class isn't a control on your form; you create it in code.
- **[BarcodeFrame](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodeframe/llms-full.txt)** places the barcode in the document with a name, an ID, a size and a position, like an image.

[Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/barcodes-property/llms-full.txt) returns the [BarcodeCollection](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodecollection/llms-full.txt) of the text part with the input focus. A header has its own, [HeaderFooter.Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/headerfooter/barcodes-property/llms-full.txt), for a code that appears on every page. Barcodes are part of the Enterprise and Professional editions; see [Editions and Feature Availability](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/overview/editions/llms-full.txt).

The following packing slip shows the kinds of codes this page creates: a QR code at the top and a linear barcode in each row of the item table.

![A packing slip with a QR code in the upper right corner and a linear barcode with its digits at the end of each item row.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/packing-slip-barcodes.4a025714.webp)

### Insert a QR Code

The following handler anchors a dark blue QR code with a link at the right edge of the paragraph with the input position:

```csharp
private void insertQrCodeButton_Click(object sender, EventArgs e)
{
    const string portalLink = "https://www.textcontrol.com";

    // The barcode: type first, then the length and the text
    TXBarcodeControl qrCode = new TXBarcodeControl();
    qrCode.BarcodeType = BarcodeType.QRCode;
    qrCode.UpperTextLength = portalLink.Length;
    qrCode.Text = portalLink;
    qrCode.ForeColor = Color.DarkBlue;

    // The frame places the barcode in the document, 1 x 1 inch
    BarcodeFrame qrFrame = new BarcodeFrame(qrCode)
    {
        Name = "portal-link",
        Size = new Size(1440, 1440)
    };

    // Anchored to the paragraph at the input position, the text flows around it
    textControl1.Barcodes.Add(qrFrame, TXTextControl.HorizontalAlignment.Right, -1,
        FrameInsertionMode.DisplaceText);
}
```

The code works as follows:

- [UpperTextLength](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/uppertextlength-property/llms-full.txt) is the maximum number of characters and [Text](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/text-property/llms-full.txt) the encoded text. Both throw an `ArgumentException` when the value isn't valid for the barcode type, so set the type first.
- [ForeColor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/forecolor-property/llms-full.txt) and [BackColor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/backcolor-property/llms-full.txt) are the colors of the code and its background, and [Angle](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/angle-property/llms-full.txt) rotates it.
- The [BarcodeFrame](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodeframe/constructor/llms-full.txt) constructor takes the barcode, and `Size` is the size of the frame in twips.
- [BarcodeCollection.Add](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodecollection/add-method/llms-full.txt) has the placements of all frames. `DisplaceText`, a value of [FrameInsertionMode](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/frameinsertionmode/enumeration/llms-full.txt), lets the text flow around the code.

### Insert a Barcode With Text

A linear barcode can show its text below or above the bars. The following handler checks an invoice number, then inserts it as a Code 128 barcode inline with the text:

```csharp
private void insertBarcodeButton_Click(object sender, EventArgs e)
{
    string invoiceNumber = "INV-2025-001";

    // Check the text before it is assigned
    string errorMessage;

    if (!TXBarcodeControl.IsTextValid(BarcodeType.Code128, invoiceNumber, out errorMessage))
    {
        MessageBox.Show(errorMessage);
        return;
    }

    TXBarcodeControl code128 = new TXBarcodeControl();
    code128.BarcodeType = BarcodeType.Code128;
    code128.UpperTextLength = invoiceNumber.Length;
    code128.Text = invoiceNumber;
    code128.ShowText = true;
    code128.AdditionalText = "Invoice number";
    code128.TextAlignment = TextAlignment.Bottom;

    // Inline, like a single character, at the input position
    textControl1.Barcodes.Add(new BarcodeFrame(code128) { Size = new Size(4320, 1080) }, -1);
}
```

- The static [IsTextValid](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/istextvalid-method/llms-full.txt) checks a text for a barcode type and returns the error message when it isn't valid, which is safer than catching the exception of `Text` when the value comes from a user.
- [ShowText](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/showtext-property/llms-full.txt) shows the encoded text of a one-dimensional barcode, and [AdditionalText](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/additionaltext-property/llms-full.txt) adds a text of your own. [TextAlignment](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/textalignment-property/llms-full.txt) puts both at the `Bottom`, the default, or the `Top`.

To show a code on every page, add it to the header, for example `header.Barcodes.Add(frame, TXTextControl.HorizontalAlignment.Right, -1, FrameInsertionMode.AboveTheText)`. To place it on one page, use the overload with a page number and a location: `textControl1.Barcodes.Add(frame, 1, new Point(8640, 720), FrameInsertionMode.AboveTheText)`.

### Change and Remove Barcodes

[BarcodeFrame.Barcode](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodeframe/barcode-property/llms-full.txt) returns the barcode of a frame. Changes to the barcode aren't shown until you call [Refresh](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodeframe/refresh-method/llms-full.txt):

```csharp
private void updateBarcodeButton_Click(object sender, EventArgs e)
{
    // null if no barcode has this name
    BarcodeFrame frame = textControl1.Barcodes.GetItem("portal-link");

    if (frame == null)
    {
        return;
    }

    TXBarcodeControl barcode = (TXBarcodeControl)frame.Barcode;
    barcode.UpperTextLength = 40;
    barcode.Text = "https://www.textcontrol.com/blog/";

    // Changes to the barcode are shown after Refresh
    frame.Refresh();
}
```

[BarcodeCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodecollection/getitem-method/llms-full.txt) returns a barcode by its name or ID, or `null`, and [Remove](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodecollection/remove-method/llms-full.txt) deletes it from the document. The [BarcodeCreated](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/barcodecreated-event/llms-full.txt) and [BarcodeDeleted](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/barcodedeleted-event/llms-full.txt) events of the `TextControl` report barcodes that are created and deleted. Programmatic changes to a barcode aren't added to the undo history of the editor; [AddUndoUnit](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/barcodeframe/addundounit-method/llms-full.txt) adds the current state of the barcode to it.

[TXBarcodeControl.SaveImage](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-barcode/txbarcodecontrol/saveimage-method/llms-full.txt) writes a barcode to an image file or a stream, for example `barcode.SaveImage("qrcode.png", System.Drawing.Imaging.ImageFormat.Png)`.

### Add Charts

A chart in a document is a [ChartFrame](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/chartframe/llms-full.txt). The frame places the chart, while the chart itself is a chart control of the type `System.Windows.Forms.DataVisualization.Charting.Chart`, which holds its appearance and data. Microsoft didn't port this library to .NET, so a .NET project references a port of it before it can use charts. [Migrating from .NET Framework to .NET](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/upgrading/from-dotnet-framework/#charts) describes how to build and install the package from Text Control's fork.

The following handler binds a chart to a `DataTable` and inserts it at the input position. The code follows Text Control's how-to sample for charts, installed with the product under *Howto\\Charts*:

```csharp
private void insertChartButton_Click(object sender, EventArgs e)
{
    // Sample data: one row per country
    DataTable sales = new DataTable("sales");
    sales.Columns.Add("Country", typeof(string));
    sales.Columns.Add("Value", typeof(int));
    sales.Rows.Add("United States", 100);
    sales.Rows.Add("Germany", 120);
    sales.Rows.Add("Japan", 140);

    // A chart control with one series and one chart area
    Chart chart = new Chart();
    chart.Series.Add("series1");
    chart.ChartAreas.Add("area1");

    // Bind the series to the columns of the table
    chart.DataSource = sales;
    chart.Series[0].XValueMember = "Country";
    chart.Series[0].YValueMembers = "Value";
    chart.DataBind();

    // The frame places the chart in the document
    ChartFrame chartFrame = new ChartFrame(chart);
    chartFrame.Name = "sales";

    textControl1.Charts.Add(chartFrame, -1);
}
```

The code works as follows:

- `Series`, `ChartAreas`, `DataSource`, `XValueMember`, `YValueMembers` and `DataBind` belong to the chart control, not to TX Text Control.
- The [ChartFrame](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/chartframe/constructor/llms-full.txt) constructor takes the chart. Like a text field, the frame has a [Name](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/framebase/name-property/llms-full.txt) that identifies the chart, here the name of the data it shows.
- [Charts](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/charts-property/llms-full.txt) returns the [ChartCollection](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/chartcollection/llms-full.txt) of the text part with the input focus, and [Add](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/chartcollection/add-method/llms-full.txt) inserts the frame like an image.

### Fill the Charts of a Template With Data

The second part of the how-to sample loads a template with named charts and fills each chart from the table of a `DataSet` with the same name:

```csharp
private void mergeChartsButton_Click(object sender, EventArgs e)
{
    DataSet data = new DataSet();
    data.ReadXml("Data.xml");

    foreach (ChartFrame chartFrame in textControl1.Charts)
    {
        // Only charts named like a table of the data set
        if (!data.Tables.Contains(chartFrame.Name))
        {
            continue;
        }

        DataTable table = data.Tables[chartFrame.Name];
        Chart chart = (Chart)chartFrame.Chart;

        // The first two columns are the x and y values
        chart.Series[0].XValueMember = table.Columns[0].ColumnName;
        chart.Series[0].YValueMembers = table.Columns[1].ColumnName;
        chart.DataSource = table;
        chart.DataBind();

        // Show the new data in the document
        chartFrame.Refresh();
    }
}
```

[ChartFrame.Chart](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/chartframe/chart-property/llms-full.txt) returns the chart control, and [ChartFrame.Refresh](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-datavisualization/chartframe/refresh-method/llms-full.txt) shows the changed chart. The result in the sample is a bar chart of the data:

![A Windows Forms window of the charts how-to sample showing a document titled A Sample Chart Template with a bar chart of values per country.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/chart-merged-from-xml.9b230768.webp)

A mail merge fills charts of a template as well, and [MailMerge.ChartMerged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/chartmerged-event/llms-full.txt) occurs for each chart it has merged; the blog article [Using MailMerge with Chart Objects and JSON Data](https://www.textcontrol.com/blog/2019/07/18/using-mailmerge-with-chart-objects-and-json-data/) connects a chart to data this way. The blog article [Using Charts with TX Text Control .NET for Windows 31.0 in .NET 6](https://www.textcontrol.com/blog/2022/11/02/using-charts-with-tx-text-control-net-for-windows-3100-in-net-6/) shows the chart package in a .NET project with screenshots.

### Next Steps

- [Images, Text Frames, and Shapes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/images-shapes/llms-full.txt): the other kinds of frames.
- [Charts and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/charts-barcodes/llms-full.txt): charts and barcodes from the user's side.
- [Integrating Charts and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/integration/charts-barcodes/llms-full.txt): the references and controls a project needs.
- [Images and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/images-barcodes/llms-full.txt): fill barcodes of a template with data.

---

## Nearby

- **Previous:** [Images, Text Frames, and Shapes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/images-shapes/llms-full.txt)
- **Next:** [Sections, Pages, Headers, and Footers](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/sections-headers/llms-full.txt)
