easyCardsWinForms 1.7.0

dotnet add package easyCardsWinForms --version 1.7.0
                    
NuGet\Install-Package easyCardsWinForms -Version 1.7.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="easyCardsWinForms" Version="1.7.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="easyCardsWinForms" Version="1.7.0" />
                    
Directory.Packages.props
<PackageReference Include="easyCardsWinForms" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add easyCardsWinForms --version 1.7.0
                    
#r "nuget: easyCardsWinForms, 1.7.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package easyCardsWinForms@1.7.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=easyCardsWinForms&version=1.7.0
                    
Install as a Cake Addin
#tool nuget:?package=easyCardsWinForms&version=1.7.0
                    
Install as a Cake Tool

easyCardsWinForms

easyCardsWinForms is a small WinForms library for building card-based UI from layout primitives.

The default card layout stacks primitives horizontally. To put text lines on top of each other, place them inside a vertical StackPrimitive.

Core Idea

EasyCard card = new EasyCard(
    new ImagePrimitive(photoBytes) { Width = 140, Height = 140 },
    new StackPrimitive(CardStackDirection.Vertical,
        new TextPrimitive("Test object") { TextFont = new Font("Arial", 11, FontStyle.Bold) },
        new TextPrimitive("2500") { TextColor = Color.FromArgb(40, 167, 69) },
        new SpacerPrimitive() { Height = 20 },
        new TextPrimitive("In stock") { TextAlign = ContentAlignment.MiddleCenter }
    )
    {
        Width = 160,
        Height = 140
    }
);

cardList.AddCard(card);

This renders as a horizontal card:

[ image ]  bold text
           green text

           centered text

Primitives

  • ImagePrimitive: image from Image or byte[].
  • TextPrimitive: text line with font, color, alignment, and height.
  • ButtonPrimitive: clickable button.
  • SpacerPrimitive: empty space.
  • StackPrimitive: nested horizontal or vertical layout.

Exact Example

Image, two text lines stacked vertically, spacer, centered text:

EasyCard card = new EasyCard(
    new ImagePrimitive(photoBytes)
    {
        Width = 150,
        Height = 150,
        SizeMode = PictureBoxSizeMode.Zoom
    },

    new StackPrimitive(CardStackDirection.Vertical,
        new TextPrimitive("Test object")
        {
            Height = 28,
            TextFont = new Font("Arial", 11, FontStyle.Bold),
            TextColor = Color.Black
        },

        new TextPrimitive("2500")
        {
            Height = 24,
            TextFont = new Font("Arial", 10, FontStyle.Bold),
            TextColor = Color.FromArgb(40, 167, 69)
        },

        new SpacerPrimitive()
        {
            Height = 20
        },

        new TextPrimitive("Test object")
        {
            Height = 24,
            TextFont = new Font("Arial", 9),
            TextColor = Color.Gray,
            TextAlign = ContentAlignment.MiddleCenter
        }
    )
    {
        Width = 170,
        Height = 150,
        Gap = 4
    }
);

card.Size = new Size(360, 180);
card.CardPadding = 10;
card.Gap = 10;

Button Example

ButtonPrimitive button = new ButtonPrimitive("Add to cart")
{
    Width = 150,
    Height = 34,
    ButtonBackColor = Color.FromArgb(0, 120, 215),
    ButtonForeColor = Color.White
};

button.Click += (sender, e) =>
{
    MessageBox.Show("Added to cart");
};

EasyCard card = new EasyCard(
    new ImagePrimitive(photoBytes) { Width = 140, Height = 140 },
    new StackPrimitive(CardStackDirection.Vertical,
        new TextPrimitive("Рубашка") { TextFont = new Font("Arial", 11, FontStyle.Bold) },
        new TextPrimitive("1800 руб.") { TextColor = Color.FromArgb(40, 167, 69) },
        new SpacerPrimitive() { Height = 12 },
        button
    )
    {
        Width = 160,
        Height = 140
    }
);

Card Click Event

Use CardClick to run code when the card is clicked. The click is also raised when the user clicks a primitive inside the card, such as text or an image.

card.CardClick += (sender, e) =>
{
    MessageBox.Show("Card clicked");
};

Use CardDataClick when you need the object attached through DataItem:

card.DataItem = product;

card.CardDataClick += (sender, e) =>
{
    Product clickedProduct = (Product)e.DataItem;
    MessageBox.Show(clickedProduct.Name);
};

For a list of cards, handle clicks from EasyCardList:

cardList.CardClick += (sender, e) =>
{
    Product clickedProduct = (Product)e.DataItem;
    MessageBox.Show(clickedProduct.Name);
};

Attached Data Object

Attach any object to a card with DataItem, then read it in CardDataClick.

DataRow row = productRow;

EasyCard card = new EasyCard(
    new ImagePrimitive((byte[])row["photo"]) { Width = 140, Height = 140 },
    new StackPrimitive(CardStackDirection.Vertical,
        new TextPrimitive(row["name"].ToString()),
        new TextPrimitive($"{row["price"]}")
    )
    {
        Width = 160,
        Height = 140
    }
);

card.DataItem = row;

card.CardDataClick += (sender, e) =>
{
    DataRow clickedRow = (DataRow)e.DataItem;
    int productId = Convert.ToInt32(clickedRow["id"]);
    MessageBox.Show($"Clicked product #{productId}");
};

You can also use DataItem from a button inside the card:

public class Product
{
    public string Name { get; set; } = "";
}

Product product = new Product
{
    Name = "Test object"
};

ButtonPrimitive showButton = new ButtonPrimitive("Show")
{
    Width = 120,
    Height = 32
};

EasyCard card = new EasyCard(
    CardStackDirection.Vertical,
    new TextPrimitive(product.Name)
    {
        Height = 30
    },
    showButton
)
{
    DataItem = product,
    Size = new Size(300, 120)
};

showButton.Click += (sender, e) =>
{
    if (card.DataItem is Product product)
    {
        MessageBox.Show(product.Name);
    }
};

cardList.AddCard(card);

EasyCardList also passes the attached row/object through its events:

cardList.CardClick += (sender, e) =>
{
    DataRow row = (DataRow)e.DataItem;
};

Vertical Card

If you want the whole card to stack vertically instead of horizontally:

EasyCard card = new EasyCard(
    CardStackDirection.Vertical,
    new ImagePrimitive(photoBytes) { Height = 160 },
    new TextPrimitive("Test object") { TextFont = new Font("Arial", 11, FontStyle.Bold) },
    new TextPrimitive("2500") { TextColor = Color.FromArgb(40, 167, 69) }
);

EasyCardList

EasyCardList is a scrollable, wrapping container for any number of EasyCard controls. Use it when you do not want to create a FlowLayoutPanel, enable scrolling, and configure card positioning yourself.

EasyCardList cardList = new EasyCardList();
cardList.Dock = DockStyle.Fill;
this.Controls.Add(cardList);

EasyCard dressCard = new EasyCard(
    new ImagePrimitive(dressPhotoBytes) { Width = 140, Height = 140 },
    new StackPrimitive(CardStackDirection.Vertical,
        new TextPrimitive("Платье") { TextFont = new Font("Arial", 11, FontStyle.Bold) },
        new TextPrimitive("2500 руб.") { TextColor = Color.FromArgb(40, 167, 69) }
    )
    {
        Width = 160,
        Height = 140
    }
);

cardList.AddCard(dressCard);

You can add cards one by one or in batches:

cardList.AddCard(card);
cardList.AddCards(card1, card2, card3);
cardList.InsertCard(0, featuredCard);
cardList.RemoveCard(oldCard);
cardList.ClearCards();

EasyCardList applies CardMargin to every added card by default:

cardList.CardMargin = new Padding(8);
cardList.ApplyCardMargin = true;

Set StretchCardsToWidth to make each card fill the available container width:

cardList.StretchCardsToWidth = true;
cardList.AddCards(card1, card2, card3);

In this mode, EasyCardList uses a vertical flow:

cardList.WrapContents = false;
cardList.FlowDirection = FlowDirection.TopDown;

It also forwards card clicks with the original DataItem:

card.DataItem = productRow;

cardList.CardClick += (sender, e) =>
{
    DataRow row = (DataRow)e.DataItem;
    int productId = Convert.ToInt32(row["id"]);
    MessageBox.Show($"Clicked product #{productId}");
};

Styling

card.Size = new Size(360, 180);
card.CardPadding = 10;
card.Gap = 8;
card.BackColor = Color.White;
card.BorderRadius = 8;
card.BorderStyle = BorderStyle.None;
card.BorderColor = Color.LightGray;

Per-Primitive Customization

Every primitive inherits common WinForms customization from CardPrimitive:

new TextPrimitive("Custom text")
{
    Width = 180,
    Height = 30,
    Margin = new Padding(4),
    Padding = new Padding(6, 0, 6, 0),
    Anchor = AnchorStyles.Left | AnchorStyles.Right,
    Dock = DockStyle.None,
    Visible = true,
    Enabled = true,
    BackColor = Color.WhiteSmoke,
    ForeColor = Color.Black,
    Font = new Font("Arial", 9),
    Cursor = Cursors.Hand,
    Name = "txtProductTitle",
    Tag = 123
};

For properties not directly exposed, use ConfigureControl:

new TextPrimitive("Raw WinForms access")
{
    ConfigureControl = control =>
    {
        Label label = (Label)control;
        label.RightToLeft = RightToLeft.No;
        label.UseCompatibleTextRendering = true;
    }
};

Primitive-specific properties are also available:

new TextPrimitive("Price")
{
    TextFont = new Font("Arial", 12, FontStyle.Bold),
    TextColor = Color.Green,
    TextBackColor = Color.Transparent,
    TextAlign = ContentAlignment.MiddleCenter,
    BorderStyle = BorderStyle.None
};

public static string defaultImage = Path.Combine(AppContext.BaseDirectory, "picture.png");
new ImagePrimitive(photoBytes)
{
    ImageBackColor = Color.Gainsboro,
    ImageBorderStyle = BorderStyle.FixedSingle,
    SizeMode = PictureBoxSizeMode.Zoom
};

new ButtonPrimitive("Add to cart")
{
    ButtonBackColor = Color.FromArgb(0, 120, 215),
    ButtonForeColor = Color.White,
    ButtonFlatStyle = FlatStyle.Flat,
    BorderSize = 0,
    TextAlign = ContentAlignment.MiddleCenter
};

Target Framework

This package targets net6.0-windows, net8.0-windows, net9.0-windows, and net10.0-windows, and uses Windows Forms.

Product Compatible and additional computed target framework versions.
.NET net6.0-windows7.0 is compatible.  net7.0-windows was computed.  net8.0-windows was computed.  net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net9.0-windows7.0 is compatible.  net10.0-windows was computed.  net10.0-windows7.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0-windows7.0

    • No dependencies.
  • net6.0-windows7.0

    • No dependencies.
  • net8.0-windows7.0

    • No dependencies.
  • net9.0-windows7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.7.0 40 6/4/2026
1.6.3 46 6/3/2026
1.6.2 44 6/3/2026
1.6.1 42 6/3/2026
1.6.0 44 6/3/2026
1.5.0 86 5/31/2026