ImGuiDatePicker.NET
1.0.0
dotnet add package ImGuiDatePicker.NET --version 1.0.0
NuGet\Install-Package ImGuiDatePicker.NET -Version 1.0.0
<PackageReference Include="ImGuiDatePicker.NET" Version="1.0.0" />
<PackageVersion Include="ImGuiDatePicker.NET" Version="1.0.0" />
<PackageReference Include="ImGuiDatePicker.NET" />
paket add ImGuiDatePicker.NET --version 1.0.0
#r "nuget: ImGuiDatePicker.NET, 1.0.0"
#:package ImGuiDatePicker.NET@1.0.0
#addin nuget:?package=ImGuiDatePicker.NET&version=1.0.0
#tool nuget:?package=ImGuiDatePicker.NET&version=1.0.0
ImGuiDatePicker.NET
English | 日本語
An ImGui-based date picker widget for Hexa.NET.ImGui. It can be rendered as a combo box that expands into a month/year navigator and calendar grid, or as a standalone popup that you open from your own button or icon.
This project is a C# port of DnA-IntRicate/ImGuiDatePicker (originally written in C++ for Dear ImGui), with additional features added on top of the original implementation. Credit for the original design and calendar logic goes to the upstream project.
Added on top of the original
Beyond the port itself, this version adds:
- A
DatePickerOptionsobject that replaces the long parameter lists of the original - Built-in localization (month names, day-of-week abbreviations and long date format) for many languages, selected with a single
Cultureproperty - Per-day styling through a callback: background color, tooltip and disabled state (use it for holidays, blackout dates and so on)
- Selectable date range restriction (
MinDate/MaxDate) - Nullable-date (
DateOnly?) overloads with click-to-clear support - A standalone calendar popup that can be opened from any custom button or icon
- Centered day-of-week headers and a "jump to today's month" button
Requirements
- .NET 8 or later, with C# 12 (the code uses collection expressions and
initproperties) and nullable reference types - Hexa.NET.ImGui, in a version based on Dear ImGui 1.92 or later (the code uses
PushFont(font, size)andImGuiStyle.FontSizeBase)
Installation
Install the package from NuGet:
dotnet add package ImGuiDatePicker.NET
Or, from the Package Manager Console in Visual Studio:
Install-Package ImGuiDatePicker.NET
Make sure Hexa.NET.ImGui is already set up in your application and an ImGui context is active.
Everything lives in the ImGuiDatePickerNET namespace:
using ImGuiDatePickerNET;
Basic usage
Keep the selected date in a field (not a local variable), so it persists across frames.
private DateOnly selectedDate = DatePicker.Today();
// Inside your ImGui frame:
if (DatePicker.Show("Pick a date", ref selectedDate))
{
// selectedDate changed
}
Hidden label (ID only)
Prefix the label with ## to hide it and use it only as an ImGui ID:
DatePicker.Show("##MyDatePicker", ref selectedDate);
Nullable date, with click-to-clear
private DateOnly? selectedDate = null;
if (DatePicker.Show("Pick a date", ref selectedDate))
{
// selectedDate changed (it may now be null again if the user clicked
// the already-selected day to clear it)
}
Clearing can be turned off with AllowClear = false in the options. It has no effect on the non-nullable overloads, since the value can never become null.
Calendar controls
- The month combo box and year input jump directly to any month or year (1900–3000).
- The arrow buttons move one month backwards or forwards.
- The dot between the arrows moves the view to today's month. It does not select a date, and it is disabled while today is not selectable.
Options
Pass a DatePickerOptions instance as the last argument of Show / ShowPopup. Every property is init-only, so set them in an object initializer. When no options are passed, a shared default instance is used.
private readonly DatePickerOptions options = new()
{
Culture = "ja",
Width = 250.0f,
MinDate = new DateOnly(2026, 1, 1),
};
DatePicker.Show("Pick a date", ref selectedDate, options);
Options are immutable after construction, and the localized values they resolve are cached. Create the instance once and reuse it across frames instead of allocating a new one every frame.
| Property | Default | Description |
|---|---|---|
Culture |
null (English) |
IETF language tag such as "ja" or "fr-CA". Selects the built-in month names, day abbreviations and long date format. |
Months |
from Culture |
12 full month names, January first. Overrides the names from Culture. |
Days |
from Culture |
7 day-of-week abbreviations, Monday first. Overrides the abbreviations from Culture. |
DateFormat |
from Culture |
Composite format string for the preview text: {0} = year, {1} = month name, {2} = day. Combo box only. |
MinDate / MaxDate |
null |
Inclusive selectable range. Days outside it are disabled and the month navigator cannot move past it. |
DayStyle |
null |
Func<DateOnly, DayStyle> called once per rendered day. See Styling individual days. |
AllowClear |
true |
Clicking the selected day again clears it. Nullable overloads only. |
AltFont |
null |
Optional font for the month combo box and the day-of-week header row. |
Width |
200 |
Width of the combo box in pixels. Combo box only. |
ClampToBorder |
false |
Stretches the combo box to the available content width, overriding Width. Combo box only. |
ItemSpacing |
8 |
Spacing between the label and the combo box. Ignored when the label is hidden. Combo box only. |
Months must contain exactly 12 entries and Days exactly 7; otherwise an ArgumentException is thrown.
Restricting the selectable range
private readonly DatePickerOptions options = new()
{
MinDate = new DateOnly(2026, 1, 1),
MaxDate = new DateOnly(2026, 12, 31),
};
Styling individual days
DayStyle is called for every visible day and returns a DayStyle with an optional background color, an optional tooltip and a disabled flag. This covers holidays, blackout dates and any other per-day rule.
private static readonly HashSet<DateOnly> Holidays = [new(2026, 1, 1), new(2026, 12, 25)];
private static readonly HashSet<DateOnly> BlackoutDates = [new(2026, 9, 5), new(2026, 9, 6)];
private readonly DatePickerOptions options = new()
{
DayStyle = date =>
{
if (BlackoutDates.Contains(date))
return new DayStyle(Disabled: true, Tooltip: "Unavailable");
if (Holidays.Contains(date))
return new DayStyle(BackgroundColor: 0xFF3030A0, Tooltip: "Holiday");
return DayStyle.None;
},
};
BackgroundColoris a packed ABGR color (Dear ImGui'sImU32layout). It is ignored on the currently selected day, which always uses ImGui's active-item color.Tooltipis shown while the day is hovered, even if the day is selected or disabled.Disabledis combined with theMinDate/MaxDatecheck using OR: a day is disabled if either condition holds.
Standalone popup
To open the calendar from your own button, icon or any other widget, use OpenPopup and ShowPopup instead of Show:
if (ImGui.Button("Pick a date"))
DatePicker.OpenPopup("##datePopup");
if (DatePicker.ShowPopup("##datePopup", ref selectedDate, options))
{
// selectedDate changed
}
- Call
OpenPopupright after the widget that opens the popup. By default the popup appears directly below that widget; passanchorToLastItem: falseto open it at the mouse position instead. - Call
ShowPopupevery frame. It draws nothing while the popup is closed, and the popup closes when the user picks a day or clicks outside of it. OpenPopupandShowPopupmust be called from the same ImGui window and ID stack scope (for example, inside the samePushIDblock).ShowPopuphas bothref DateOnlyandref DateOnly?overloads, likeShow.Width,ClampToBorder,ItemSpacingandDateFormatare ignored by the popup, since it has no label or preview text.- Emoji such as 📅 are not available in ImGui's default font. Use an icon font or an image button for the icon.
Localization
Set Culture to pick the built-in month names, day-of-week abbreviations and long date format:
var ja = new DatePickerOptions { Culture = "ja" }; // 2026年9月21日
var de = new DatePickerOptions { Culture = "de" }; // 21. September 2026
// Follow the OS UI language
var auto = new DatePickerOptions { Culture = CultureInfo.CurrentUICulture.Name };
Built-in languages (case-insensitive tags): en, ja, zh, zh-TW, ko, es, fr, it, pt, ro, de, nl, sv, da, nb, ru, uk, pl, cs, fi, hu, el, tr, he, ar, hi, th, vi, id. The full list is available at runtime as CalendarLocalization.Months.Keys.
Lookup falls back from the exact tag to its parent language (fr-CA → fr), and finally to English. zh-HK, zh-MO and zh-Hant* use zh-TW, and no / nn use nb.
To switch the language while the application is running, create a new DatePickerOptions with the new Culture.
Custom names and formats
Explicitly set values take precedence over Culture:
var options = new DatePickerOptions
{
Culture = "ja",
DateFormat = "{0}/{1}/{2}", // year/month name/day
// Or replace the names completely:
// Months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
// Days = ["M", "T", "W", "T", "F", "S", "S"],
};
Fonts
Dear ImGui only draws the glyphs that are loaded into its font atlas. To show Japanese, Chinese, Korean, Cyrillic, Greek, Thai, Hebrew, Arabic or Devanagari text, load a font that contains the matching glyph ranges. The preview text of the combo box uses your default font, so it needs those glyphs too; AltFont only affects the month combo box and the header row.
API overview
| Member | Description |
|---|---|
DatePicker.Show(label, ref v, options) |
Combo box date picker. Overloads for ref DateOnly and ref DateOnly?. Returns true when the date changed. |
DatePicker.OpenPopup(popupId, anchorToLastItem) |
Opens the standalone calendar popup. |
DatePicker.ShowPopup(popupId, ref v, options) |
Renders the standalone calendar popup. Overloads for ref DateOnly and ref DateOnly?. Returns true when the date changed. |
DatePickerOptions |
All configuration, as init-only properties. Also exposes DefaultMonths and DefaultDays (English). |
DayStyle |
Per-day background color, tooltip and disabled state. DayStyle.None is the neutral default. |
CalendarLocalization |
Built-in per-language tables: Months, Days, LongDateFormats, and the lookup helpers GetMonths, GetDays and GetLongDateFormat. |
DatePicker.Today() |
The current date, in UTC. |
DatePicker.MinYear / MaxYear |
The absolute earliest / latest selectable year (1900–3000). |
Known limitations
- The combo box shows "Select a date" when no date is selected, and this text is not localized yet.
- Month names in the preview text are always in their standalone (nominative) form. Languages that inflect month names inside a date, such as Russian, Ukrainian, Polish, Czech, Greek and Finnish, may read unnaturally. Thai dates use the Gregorian year rather than the Buddhist Era.
- Right-to-left layout and complex-script shaping (Arabic, Hebrew, Hindi, Thai) are not provided by Dear ImGui, so these strings may not render correctly. Check them in your own setup before relying on them.
DatePicker.Today()uses UTC, so around midnight it can differ from the local date. If you need the local date, compute it yourself and pass it in as the selected date.
License
This project is licensed under the MIT License, the same license as the upstream project it is ported from.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Hexa.NET.ImGui (>= 3.1.0-experimental)
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.0.0 | 85 | 9/21/2026 |
A localized date picker widget for Hexa.NET.ImGui, as a combo box or a standalone popup.