Test in production without watermarks.
Works wherever you need it to.
Get 30 days of fully functional product.
Have it up and running in minutes.
Full access to our support engineering team during your product trial
In C#, the ObservableCollection
IronPDF is a robust library for generating PDFs in C#. With its HTML-to-PDF conversion capabilities, it’s easy to create high-quality PDFs, whether you need to generate invoices, reports, or any other documents based on real-time data. In this article, we’ll show you how to integrate the ObservableCollection class with IronPDF, leveraging data binding to generate a PDF that dynamically updates as data changes.
The ObservableCollection
The ObservableCollection automatically handles changes to the entire collection, making it easy to manage and display dynamic data collection in your application.
Add from PixabayUpload
or drag and drop an image here
Add image alt text
As we mentioned at the start of this article, IronPDF is a .NET PDF generation library that makes it easy to create, modify, and render PDF documents. Unlike some other PDF libraries, IronPDF provides a rich set of features that simplify working with PDFs, such as converting HTML to PDF, adding watermarks, manipulating existing PDFs, and more.
IronPDF also allows developers to render PDFs from different data sources, including HTML, images, and plain text, which can be particularly useful when you need to present dynamic data. With IronPDF’s API, you can generate high-quality PDFs, including detailed layouts, tables, images, and styles.
To get started with IronPDF, you need to install the library via NuGet. You can add it to your project by running the following command in the Package Manager Console:
Install-Package IronPdf
Install-Package IronPdf
Once installed, you can initialize IronPDF and use its powerful features. For this article, we’ll focus on generating PDFs from dynamic data in an ObservableCollection.
Let’s imagine a scenario where you need to generate an invoice PDF from a list of items stored in an ObservableCollection. As items are added or removed from the collection, the PDF should be regenerated automatically to reflect the current state of the data.
For this task, ObservableCollection provides an easy way to manage the items in the invoice, while IronPDF will allow us to generate and export the invoice to a PDF format.
To bind the data in an ObservableCollection to a PDF, you need to loop through the collection and add its items to the PDF content. IronPDF provides methods to create tables, add text, and customize the layout, making it easy to represent the data in a structured format.
For instance, if you have an invoice with several items, you can dynamically generate the PDF by looping through the ObservableCollection and adding each item to a table or list in the document. IronPDF allows for a high level of customization, including adjusting fonts, borders, and even including images like logos or barcodes.
Let's look at a simple example to demonstrate how this works. Suppose you have a collection of people (represented by the Person class), and you want to generate a PDF that reflects the details of these people. Each time a new person is added to the collection, the PDF will automatically update.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
In this case, the Person class contains basic properties such as Name and Age. We will use this class in conjunction with the ObservableCollection to dynamically generate a PDF.
using System.Collections.ObjectModel;
var collection = new ObservableCollection<Person>
{
new Person { Name = "John Doe", Age = 30 },
new Person { Name = "Jane Smith", Age = 28 }
};
using System.Collections.ObjectModel;
var collection = new ObservableCollection<Person>
{
new Person { Name = "John Doe", Age = 30 },
new Person { Name = "Jane Smith", Age = 28 }
};
This ObservableCollection contains a collection of Person objects, each with a Name and Age. When an item is added or removed, event handlers are triggered, which we'll use to update the PDF dynamically.
In this example, we subscribe to the CollectionChanged event of the ObservableCollection class to automatically regenerate the PDF whenever the collection changes. This is useful if you need to respond to changes such as adding or removing a Person object.
// Subscribe to the ObservableCollection's CollectionChanged event
collection.CollectionChanged += (object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) =>
{
// Regenerate the PDF whenever the collection changes
GeneratePersonPDF(collection);
};
// Subscribe to the ObservableCollection's CollectionChanged event
collection.CollectionChanged += (object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) =>
{
// Regenerate the PDF whenever the collection changes
GeneratePersonPDF(collection);
};
You can add a new Person to the collection, and the entire collection will trigger the event handler to regenerate the PDF. This approach automatically handles changes to the entire list of people.
// Adding a new person to the collection
collection.Add(new Person { Name = "Alice Brown", Age = 32 });
// Adding a new person to the collection
collection.Add(new Person { Name = "Alice Brown", Age = 32 });
Each time you add a new person to the collection, the PDF will regenerate, including the new entry.
You can also bind the age property of a Person to some external system (such as the UI or other parts of the application) to automatically reflect changes.
Here’s an example of how the Age property would be bound in the Person class:
public class Person
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set
{
_age = value;
// Raise property changed event here if using data binding
}
}
}
public class Person
{
public string Name { get; set; }
private int _age;
public int Age
{
get { return _age; }
set
{
_age = value;
// Raise property changed event here if using data binding
}
}
}
Let’s demonstrate using binding age to a UI element, updating the age value and observing the changes being reflected in the collection:
ObservableCollection<Person> people = new ObservableCollection<Person>
{
new Person { Name = "John", Age = 30 },
new Person { Name = "Jane", Age = 28 }
};
// Binding the Age of the first person to a UI element (pseudo-code)
someUIElement.Text = people[0].Age.ToString();
ObservableCollection<Person> people = new ObservableCollection<Person>
{
new Person { Name = "John", Age = 30 },
new Person { Name = "Jane", Age = 28 }
};
// Binding the Age of the first person to a UI element (pseudo-code)
someUIElement.Text = people[0].Age.ToString();
Now that we've set up the ObservableCollection and added event handlers, it's time to focus on generating a PDF that reflects the dynamic collection of people.
using IronPdf;
public void GeneratePersonPDF(ObservableCollection<Person> people)
{
var pdf = new ChromePdfRenderer(); // Initialize IronPDF's ChromePdfRenderer class
// Create HTML content representing the people in the collection
var htmlContent = "<h1>People Information</h1><table border='1' cellpadding='5' cellspacing='0'>" +
"<tr><th>Name</th><th>Age</th></tr>";
foreach (var person in people)
{
htmlContent += $"<tr><td>{person.Name}</td><td>{person.Age}</td></tr>";
}
htmlContent += "</table>";
// Convert the HTML content to a PDF
var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to disk
pdfDocument.SaveAs("PeopleInformation.pdf");
}
using IronPdf;
public void GeneratePersonPDF(ObservableCollection<Person> people)
{
var pdf = new ChromePdfRenderer(); // Initialize IronPDF's ChromePdfRenderer class
// Create HTML content representing the people in the collection
var htmlContent = "<h1>People Information</h1><table border='1' cellpadding='5' cellspacing='0'>" +
"<tr><th>Name</th><th>Age</th></tr>";
foreach (var person in people)
{
htmlContent += $"<tr><td>{person.Name}</td><td>{person.Age}</td></tr>";
}
htmlContent += "</table>";
// Convert the HTML content to a PDF
var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to disk
pdfDocument.SaveAs("PeopleInformation.pdf");
}
Here’s an example of how to generate a PDF from an ObservableCollection of invoice items using IronPDF:
This class represents an item in the invoice, with properties for item name, quantity, price, and total price.
public class InvoiceItem
{
public string ItemName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal Total => Quantity * Price;
}
public class InvoiceItem
{
public string ItemName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal Total => Quantity * Price;
}
This example initializes an ObservableCollection containing several invoice items. You can dynamically add, remove, or modify the items in this collection.
ObservableCollection<InvoiceItem> invoiceItems = new ObservableCollection<InvoiceItem>
{
new InvoiceItem { ItemName = "Item 1", Quantity = 2, Price = 10.00m },
new InvoiceItem { ItemName = "Item 2", Quantity = 1, Price = 25.00m },
new InvoiceItem { ItemName = "Item 3", Quantity = 5, Price = 5.00m }
};
ObservableCollection<InvoiceItem> invoiceItems = new ObservableCollection<InvoiceItem>
{
new InvoiceItem { ItemName = "Item 1", Quantity = 2, Price = 10.00m },
new InvoiceItem { ItemName = "Item 2", Quantity = 1, Price = 25.00m },
new InvoiceItem { ItemName = "Item 3", Quantity = 5, Price = 5.00m }
};
Here, we create a function to generate the PDF. This function uses the data in the ObservableCollection and converts it to HTML, which is then rendered as a PDF using IronPDF.
public void GenerateInvoicePDF(ObservableCollection<InvoiceItem> items)
{
var pdf = new ChromePdfRenderer(); // Initialize IronPDF's ChromePdfRenderer class
// Create HTML content representing the invoice
var htmlContent = "<h1>Invoice</h1><table border='1' cellpadding='5' cellspacing='0'>" +
"<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>";
foreach (var item in items)
{
htmlContent += $"<tr><td>{item.ItemName}</td><td>{item.Quantity}</td><td>{item.Price:C}</td><td>{item.Total:C}</td></tr>";
}
htmlContent += "</table>";
// Convert the HTML content to a PDF
var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to disk
pdfDocument.SaveAs("Invoice.pdf");
}
public void GenerateInvoicePDF(ObservableCollection<InvoiceItem> items)
{
var pdf = new ChromePdfRenderer(); // Initialize IronPDF's ChromePdfRenderer class
// Create HTML content representing the invoice
var htmlContent = "<h1>Invoice</h1><table border='1' cellpadding='5' cellspacing='0'>" +
"<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>";
foreach (var item in items)
{
htmlContent += $"<tr><td>{item.ItemName}</td><td>{item.Quantity}</td><td>{item.Price:C}</td><td>{item.Total:C}</td></tr>";
}
htmlContent += "</table>";
// Convert the HTML content to a PDF
var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to disk
pdfDocument.SaveAs("Invoice.pdf");
}
Because ObservableCollection automatically notifies changes, you can easily regenerate the PDF whenever the collection is updated. For example, if an item is added or removed, the PDF can be regenerated with the updated data.
Here’s how you can subscribe to the CollectionChanged event and regenerate the PDF whenever the collection changes:
// Subscribe to the ObservableCollection's CollectionChanged event
invoiceItems.CollectionChanged += (sender, e) =>
{
// Regenerate the PDF whenever the collection changes
GenerateInvoicePDF(invoiceItems);
};
// Subscribe to the ObservableCollection's CollectionChanged event
invoiceItems.CollectionChanged += (sender, e) =>
{
// Regenerate the PDF whenever the collection changes
GenerateInvoicePDF(invoiceItems);
};
You can now test by adding new items to the ObservableCollection and observing how the PDF is regenerated automatically.
// Adding a new item to the ObservableCollection
invoiceItems.Add(new InvoiceItem { ItemName = "Item 4", Quantity = 3, Price = 12.50m });
// Adding a new item to the ObservableCollection
invoiceItems.Add(new InvoiceItem { ItemName = "Item 4", Quantity = 3, Price = 12.50m });
using System;
using System.Collections.ObjectModel;
using IronPdf;
public class InvoiceItem
{
public string ItemName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
// Property to calculate the total price for each item
public decimal Total => Quantity * Price;
}
public class InvoiceGenerator
{
// Function to generate the invoice PDF
public void GenerateInvoicePDF(ObservableCollection<InvoiceItem> items)
{
var pdf = new ChromePdfRenderer(); // Initialize IronPDF's ChromePdfRenderer class
// Create HTML content representing the invoice
var htmlContent = "<h1>Invoice</h1><table border='1' cellpadding='5' cellspacing='0'>" +
"<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>";
foreach (var item in items)
{
htmlContent += $"<tr><td>{item.ItemName}</td><td>{item.Quantity}</td><td>{item.Price:C}</td><td>{item.Total:C}</td></tr>";
}
htmlContent += "</table>";
// Convert the HTML content to a PDF
var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to disk
pdfDocument.SaveAs("Invoice.pdf");
}
// Main function to test the code
public static void Main(string[] args)
{
var invoiceItems = new ObservableCollection<InvoiceItem>
{
new InvoiceItem { ItemName = "Item 1", Quantity = 2, Price = 10.00m },
new InvoiceItem { ItemName = "Item 2", Quantity = 1, Price = 25.00m },
new InvoiceItem { ItemName = "Item 3", Quantity = 5, Price = 5.00m }
};
var invoiceGenerator = new InvoiceGenerator();
// Subscribe to the ObservableCollection's CollectionChanged event
invoiceItems.CollectionChanged += (sender, e) =>
{
// Regenerate the PDF whenever the collection changes
invoiceGenerator.GenerateInvoicePDF(invoiceItems);
};
// Generate initial PDF
invoiceGenerator.GenerateInvoicePDF(invoiceItems);
// Add a new item to the collection and automatically regenerate the PDF
invoiceItems.Add(new InvoiceItem { ItemName = "Item 4", Quantity = 3, Price = 12.50m });
// Remove an item and see the PDF update
invoiceItems.RemoveAt(0);
}
}
using System;
using System.Collections.ObjectModel;
using IronPdf;
public class InvoiceItem
{
public string ItemName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
// Property to calculate the total price for each item
public decimal Total => Quantity * Price;
}
public class InvoiceGenerator
{
// Function to generate the invoice PDF
public void GenerateInvoicePDF(ObservableCollection<InvoiceItem> items)
{
var pdf = new ChromePdfRenderer(); // Initialize IronPDF's ChromePdfRenderer class
// Create HTML content representing the invoice
var htmlContent = "<h1>Invoice</h1><table border='1' cellpadding='5' cellspacing='0'>" +
"<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>";
foreach (var item in items)
{
htmlContent += $"<tr><td>{item.ItemName}</td><td>{item.Quantity}</td><td>{item.Price:C}</td><td>{item.Total:C}</td></tr>";
}
htmlContent += "</table>";
// Convert the HTML content to a PDF
var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);
// Save the generated PDF to disk
pdfDocument.SaveAs("Invoice.pdf");
}
// Main function to test the code
public static void Main(string[] args)
{
var invoiceItems = new ObservableCollection<InvoiceItem>
{
new InvoiceItem { ItemName = "Item 1", Quantity = 2, Price = 10.00m },
new InvoiceItem { ItemName = "Item 2", Quantity = 1, Price = 25.00m },
new InvoiceItem { ItemName = "Item 3", Quantity = 5, Price = 5.00m }
};
var invoiceGenerator = new InvoiceGenerator();
// Subscribe to the ObservableCollection's CollectionChanged event
invoiceItems.CollectionChanged += (sender, e) =>
{
// Regenerate the PDF whenever the collection changes
invoiceGenerator.GenerateInvoicePDF(invoiceItems);
};
// Generate initial PDF
invoiceGenerator.GenerateInvoicePDF(invoiceItems);
// Add a new item to the collection and automatically regenerate the PDF
invoiceItems.Add(new InvoiceItem { ItemName = "Item 4", Quantity = 3, Price = 12.50m });
// Remove an item and see the PDF update
invoiceItems.RemoveAt(0);
}
}
Output
Add from PixabayUpload
or drag and drop an image here
Clear alt text
When working with large ObservableCollection instances, performance can become a concern. Regenerating a PDF each time the collection changes might be resource-intensive if there are a large number of items. To mitigate this, consider batching updates or using techniques like pagination to avoid overloading the PDF generation process.
To ensure that PDF rendering is efficient, keep the following tips in mind:
By combining C#’s ObservableCollection with IronPDF, you can easily generate dynamic PDFs that reflect real-time changes in your application’s data. Whether you're generating invoices, reports, or other documents, this approach allows you to automatically update the PDF content whenever the underlying collection changes.
The integration of ObservableCollection ensures that your application is always up-to-date with minimal effort, while IronPDF handles the heavy lifting of rendering high-quality PDFs. By following the best practices and performance tips discussed in this article, you can create a seamless PDF generation experience for your .NET applications.
Want to try IronPDF for yourself? Download the free trial today to elevate your C# PDF projects, and be sure to check out the extensive documentation section to see more of this library in action.
The ObservableCollection
Unlike List
ObservableCollection is commonly used for binding data to UI components in applications like WPF, ensuring the UI remains in sync with data changes. It's also used for dynamic data management, such as in real-time reporting and applications allowing user modifications.
IronPDF is a .NET PDF generation library that simplifies the creation, modification, and rendering of PDF documents. It supports features like HTML-to-PDF conversion, adding watermarks, and rendering PDFs from various data sources.
You can integrate ObservableCollection with IronPDF by binding the collection's data to the PDF content. As the collection changes, you can regenerate the PDF to reflect the current data, leveraging IronPDF's ability to render high-quality PDFs from dynamic data.
Data binding is achieved by iterating over the ObservableCollection and adding its items to the PDF content as structured elements like tables or lists. IronPDF's methods allow for customization of the PDF layout and content representation.
A typical scenario involves generating an invoice PDF from a list of items in an ObservableCollection. As items are added or removed, the PDF is regenerated to reflect the current state of the data, ensuring real-time accuracy.
When dealing with large collections, consider batching updates or using pagination to avoid performance bottlenecks. Minimize unnecessary re-renders and optimize layout to enhance rendering efficiency. Caching can also help for static data.
IronPDF provides a rich set of features for high-quality PDF generation, including HTML to PDF conversion, detailed layout customization, and support for various data sources. It simplifies complex PDF tasks and enhances productivity in .NET applications.