diff --git a/BytecodeApi.IniParser/IniFile.cs b/BytecodeApi.IniParser/IniFile.cs
index d21b8ed..c316a50 100644
--- a/BytecodeApi.IniParser/IniFile.cs
+++ b/BytecodeApi.IniParser/IniFile.cs
@@ -111,6 +111,31 @@ public static IniFile FromBinary(byte[] file, Encoding? encoding, IniFileParsing
return FromStream(memoryStream, encoding, parsingOptions);
}
///
+ /// Creates an object from the specified that represents the contents of an INI file.
+ ///
+ /// The that represents the contents of an INI file to read from.
+ ///
+ /// The this method creates.
+ ///
+ public static IniFile FromString(string ini)
+ {
+ return FromString(ini, null);
+ }
+ ///
+ /// Creates an object from the specified that represents the contents of an INI file.
+ ///
+ /// The that represents the contents of an INI file to read from.
+ /// A object with format specifications for INI parsing, or to use default parsing options.
+ ///
+ /// The this method creates.
+ ///
+ public static IniFile FromString(string ini, IniFileParsingOptions? parsingOptions)
+ {
+ Check.ArgumentNull(ini);
+
+ return FromBinary(ini.ToUTF8Bytes(), Encoding.UTF8, parsingOptions);
+ }
+ ///
/// Creates an object from the specified .
///
/// The from which to parse the INI file from.
@@ -242,6 +267,10 @@ public static IniFile FromStream(Stream stream, Encoding? encoding, IniFileParsi
{
ParseProperty(":");
}
+ else if (parsingOptions.AllowEmptyValues)
+ {
+ ParseProperty(null);
+ }
else
{
Abort();
@@ -265,13 +294,15 @@ void AbortIf(bool condition)
Abort();
}
}
- void ParseProperty(string delimiter)
+ void ParseProperty(string? delimiter)
{
if (!ignoreSection)
{
AbortIf(!parsingOptions.AllowGlobalProperties && section == ini.GlobalProperties);
- IniProperty property = new(line.SubstringUntil(delimiter), line.SubstringFrom(delimiter));
+ IniProperty property = delimiter != null
+ ? new(line.SubstringUntil(delimiter), line.SubstringFrom(delimiter))
+ : new(line, "");
if (parsingOptions.TrimPropertyNames)
{
@@ -448,8 +479,53 @@ void WriteSection(IniSection section)
foreach (IniProperty property in section.Properties)
{
- streamWriter.WriteLine(property.Name + delimiter + property.Value);
+ if (property.Value.IsNullOrEmpty() && formattingOptions.OmitDelimiterForEmptyValues)
+ {
+ streamWriter.WriteLine(property.Name);
+ }
+ else
+ {
+ streamWriter.WriteLine(property.Name + delimiter + property.Value);
+ }
}
}
}
+ ///
+ /// Converts this to its [] representation.
+ ///
+ ///
+ /// A new [] representing this .
+ ///
+ public byte[] Save()
+ {
+ return Save(Encoding.UTF8);
+ }
+ ///
+ /// Converts this to its [] representation.
+ ///
+ /// The encoding to use to write to the file.
+ ///
+ /// A new [] representing this .
+ ///
+ public byte[] Save(Encoding encoding)
+ {
+ return Save(encoding, null);
+ }
+ ///
+ /// Converts this to its [] representation.
+ ///
+ /// The encoding to use to write to the file.
+ /// An object specifying how to format the INI file.
+ ///
+ /// A new [] representing this .
+ ///
+ public byte[] Save(Encoding encoding, IniFileFormattingOptions? formattingOptions)
+ {
+ Check.ArgumentNull(encoding);
+
+ using MemoryStream memoryStream = new();
+ Save(memoryStream, encoding, formattingOptions);
+
+ return memoryStream.ToArray();
+ }
}
\ No newline at end of file
diff --git a/BytecodeApi.IniParser/IniFileFormattingOptions.cs b/BytecodeApi.IniParser/IniFileFormattingOptions.cs
index 311b8ea..051c9e7 100644
--- a/BytecodeApi.IniParser/IniFileFormattingOptions.cs
+++ b/BytecodeApi.IniParser/IniFileFormattingOptions.cs
@@ -11,6 +11,11 @@ public sealed class IniFileFormattingOptions
///
public IniPropertyDelimiter PropertyDelimiter { get; set; }
///
+ /// to omit the delimiter when the property value is empty; to always write the delimiter.
+ /// The default value is .
+ ///
+ public bool OmitDelimiterForEmptyValues { get; set; }
+ ///
/// to use a space before the delimiter; to append the delimiter directly after the property name.
/// The default value is .
///
diff --git a/BytecodeApi.IniParser/IniFileParsingOptions.cs b/BytecodeApi.IniParser/IniFileParsingOptions.cs
index 27b44e7..451b861 100644
--- a/BytecodeApi.IniParser/IniFileParsingOptions.cs
+++ b/BytecodeApi.IniParser/IniFileParsingOptions.cs
@@ -46,6 +46,11 @@ public sealed class IniFileParsingOptions
///
public IniPropertyDelimiter PropertyDelimiter { get; set; }
///
+ /// to allow properties with no values (only a name); to throw an .
+ /// The default value is .
+ ///
+ public bool AllowEmptyValues { get; set; }
+ ///
/// to ignore lines that start with a semicolon; to treat it as a normal character, which will be included in the property name.
/// The default value is .
///
diff --git a/BytecodeApi.Rest/GenericRestClient.cs b/BytecodeApi.Rest/GenericRestClient.cs
index 9a8557e..0e2da07 100644
--- a/BytecodeApi.Rest/GenericRestClient.cs
+++ b/BytecodeApi.Rest/GenericRestClient.cs
@@ -30,7 +30,14 @@ static GenericRestClient()
///
/// Initializes a new instance of the class.
///
- public GenericRestClient() : base("")
+ public GenericRestClient() : this("")
+ {
+ }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The base URL of the REST service. Trailing slashes will be removed.
+ public GenericRestClient(string baseUrl) : base(baseUrl)
{
}
diff --git a/BytecodeApi.Wpf/.nuget/README.md b/BytecodeApi.Wpf/.nuget/README.md
index 872ff2a..b34c4ca 100644
--- a/BytecodeApi.Wpf/.nuget/README.md
+++ b/BytecodeApi.Wpf/.nuget/README.md
@@ -8,6 +8,10 @@ See: [Examples](https://github.com/bytecode77/bytecode-api/blob/master/BytecodeA
## Changelog
+### 5.1.1 (28.07.2026)
+
+* **new:** `WindowService.DisableTransitions` property
+
### 5.1.0 (07.07.2026)
* **change:** `FileDialogs` class reworked to a fluent builder, allowing for more diverse scenarios.
diff --git a/BytecodeApi.Wpf/BytecodeApi.Wpf.csproj b/BytecodeApi.Wpf/BytecodeApi.Wpf.csproj
index 46d3c23..c30e4fc 100644
--- a/BytecodeApi.Wpf/BytecodeApi.Wpf.csproj
+++ b/BytecodeApi.Wpf/BytecodeApi.Wpf.csproj
@@ -7,9 +7,9 @@
True
- 5.1.0
- 5.1.0
- 5.1.0
+ 5.1.1
+ 5.1.1
+ 5.1.1
BytecodeApi.Wpf
diff --git a/BytecodeApi.Wpf/README.md b/BytecodeApi.Wpf/README.md
index 3c950db..e811c50 100644
--- a/BytecodeApi.Wpf/README.md
+++ b/BytecodeApi.Wpf/README.md
@@ -249,6 +249,10 @@ if (FileDialogs.OpenFolder(@"C:\path\to\directory") is string directory)
## Changelog
+### 5.1.1 (28.07.2026)
+
+* **new:** `WindowService.DisableTransitions` property
+
### 5.1.0 (07.07.2026)
* **change:** `FileDialogs` class reworked to a fluent builder, allowing for more diverse scenarios.
diff --git a/BytecodeApi.Wpf/Services/WindowService.cs b/BytecodeApi.Wpf/Services/WindowService.cs
index f9a31a5..b7c55ee 100644
--- a/BytecodeApi.Wpf/Services/WindowService.cs
+++ b/BytecodeApi.Wpf/Services/WindowService.cs
@@ -38,6 +38,10 @@ public static class WindowService
///
public static readonly DependencyProperty IsAcrylicEnabledProperty = DependencyProperty.RegisterAttached("IsAcrylicEnabled", new FrameworkPropertyMetadata(IsAcrylicEnabled_Changed));
///
+ /// Identifies the .DisableTransitions dependency property. This field is read-only.
+ ///
+ public static readonly DependencyProperty DisableTransitionsProperty = DependencyProperty.RegisterAttached("DisableTransitions", new FrameworkPropertyMetadata(DisableTransitions_Changed));
+ ///
/// Gets a value indicating whether this displays an icon.
///
/// The to check.
@@ -186,6 +190,31 @@ public static void SetIsAcrylicEnabled(DependencyObject dependencyObject, bool v
dependencyObject.SetValue(IsAcrylicEnabledProperty, value);
}
+ ///
+ /// Gets a value indicating whether transitions of this are disabled.
+ ///
+ /// The to check.
+ ///
+ /// , if transitions are disabled;
+ /// , if transitions are enabled.
+ ///
+ public static bool GetDisableTransitions(DependencyObject dependencyObject)
+ {
+ Check.ArgumentNull(dependencyObject);
+
+ return dependencyObject.GetValue(DisableTransitionsProperty);
+ }
+ ///
+ /// Enables or disables transitions on this .
+ ///
+ /// The to enable or disable transitions on.
+ /// to disable transitions; to enable transitions.
+ public static void SetDisableTransitions(DependencyObject dependencyObject, bool value)
+ {
+ Check.ArgumentNull(dependencyObject);
+
+ dependencyObject.SetValue(DisableTransitionsProperty, value);
+ }
private static void ShowIcon_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
@@ -282,6 +311,17 @@ private static void IsAcrylicEnabled_Changed(DependencyObject dependencyObject,
});
}
}
+ private static void DisableTransitions_Changed(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
+ {
+ if (dependencyObject is Window window)
+ {
+ ApplyWindowChange(window, handle =>
+ {
+ uint disableTransitions = GetDisableTransitions(dependencyObject) ? 1u : 0u;
+ Native.DwmSetWindowAttribute(handle, 3, ref disableTransitions, sizeof(int));
+ });
+ }
+ }
private static void ApplyWindowChange(Window window, Action apply)
{