easyCardsWinForms 1.7.0
dotnet add package easyCardsWinForms --version 1.7.0
NuGet\Install-Package easyCardsWinForms -Version 1.7.0
<PackageReference Include="easyCardsWinForms" Version="1.7.0" />
<PackageVersion Include="easyCardsWinForms" Version="1.7.0" />
<PackageReference Include="easyCardsWinForms" />
paket add easyCardsWinForms --version 1.7.0
#r "nuget: easyCardsWinForms, 1.7.0"
#:package easyCardsWinForms@1.7.0
#addin nuget:?package=easyCardsWinForms&version=1.7.0
#tool nuget:?package=easyCardsWinForms&version=1.7.0
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 fromImageorbyte[].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 | Versions 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. |
-
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.