diff --git a/src/AasxCore.Samm2_2_0/SammClasses.cs b/src/AasxCore.Samm2_2_0/SammClasses.cs
index 6091173e6..ef0818408 100644
--- a/src/AasxCore.Samm2_2_0/SammClasses.cs
+++ b/src/AasxCore.Samm2_2_0/SammClasses.cs
@@ -95,6 +95,20 @@ public SammPropertyUriAttribute(string uri)
}
}
+ ///
+ /// Some string based flags to attach to the property
+ ///
+ [System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = true)]
+ public class SammPropertyFlagsAttribute : System.Attribute
+ {
+ public string Flags = "";
+
+ public SammPropertyFlagsAttribute(string flags)
+ {
+ Flags = flags;
+ }
+ }
+
///
/// Shall be implemented by all non-abstract model elements
///
@@ -436,8 +450,11 @@ public bool AddOrIgnore(string prefix, string uri)
///
///
///
- public class Constraint : ModelElement
- {
+ public class Constraint : ModelElement, ISammSelfDescription
+ {
+ // self description
+ public string GetSelfName() => "samm-constraint";
+ public string GetSelfUrn() => "bamm-c:Constraint";
}
///
@@ -445,14 +462,18 @@ public class Constraint : ModelElement
///
///
///
- public class LanguageConstraint : Constraint
+ public class LanguageConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-language-constraint";
+ public new string GetSelfUrn() => "bamm-c:LanguageConstraint";
+
///
/// An ISO 639-1 [iso639] language code for the language of the value of the constrained Property,
/// e.g., "de".
///
[SammPropertyUri("bamm-c:languageCode")]
- public string? LanguageCode;
+ public string? LanguageCode { get; set; }
}
///
@@ -460,46 +481,54 @@ public class LanguageConstraint : Constraint
///
///
///
- public class LocaleConstraint : Constraint
+ public class LocaleConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-locale-constraint";
+ public new string GetSelfUrn() => "bamm-c:LocaleConstraint";
+
///
/// An IETF BCP 47 language code for the locale of the value of the constrained Property, e.g., "de-DE".
///
[SammPropertyUri("bamm-c:localeCode")]
- public string? LocaleCode;
+ public string? LocaleCode { get; set; }
}
///
/// Restricts the value range of a Property. At least one of maxValue or minValue must be present in a
/// Range Constraint.
///
- public class RangeConstraint : Constraint
+ public class RangeConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-range-constraint";
+ public new string GetSelfUrn() => "bamm-c:RangeConstraint";
+
///
/// The upper bound of a range.
///
[SammPropertyUri("bamm-c:maxValue")]
- public string? MaxValue;
+ public string? MaxValue { get; set; }
///
/// The lower bound of a range.
///
[SammPropertyUri("bamm-c:minValue")]
- public string? MinValue;
+ public string? MinValue { get; set; }
///
/// Defines whether the upper bound of a range is inclusive or exclusive. Possible values are
/// AT_MOST and LESS_THAN.
///
[SammPropertyUri("bamm-c:upperBoundDefinition")]
- public SammUpperBoundDefinition? UpperBoundDefinition;
+ public SammUpperBoundDefinition? UpperBoundDefinition { get; set; }
///
/// Defines whether the lower bound of a range is inclusive or exclusive. Possible values are
/// AT_LEAST and GREATER_THAN.
///
[SammPropertyUri("bamm-c:lowerBoundDefinition")]
- public SammLowerBoundDefinition? LowerBoundDefinition;
+ public SammLowerBoundDefinition? LowerBoundDefinition { get; set; }
}
///
@@ -507,14 +536,18 @@ public class RangeConstraint : Constraint
///
///
///
- public class EncodingConstraint : Constraint
+ public class EncodingConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-encoding-constraint";
+ public new string GetSelfUrn() => "bamm-c:EncodingConstraint";
+
///
/// Configures the encoding. This must be one of the following:
/// US-ASCII, ISO-8859-1, UTF-8, UTF-16, UTF-16BE or UTF-16LE.
///
[SammPropertyUri("bamm:value")]
- public SammEncoding? Value;
+ public SammEncoding? Value { get; set; }
}
///
@@ -526,19 +559,23 @@ public class EncodingConstraint : Constraint
///
///
///
- public class LengthConstraint : Constraint
+ public class LengthConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-length-constraint";
+ public new string GetSelfUrn() => "bamm-c:LengthConstraint";
+
///
/// The maximum length. Must be given as xsd:nonNegativeInteger.
///
[SammPropertyUri("bamm-c:maxValue")]
- public uint? MaxValue;
+ public uint? MaxValue { get; set; }
///
/// The minimum length. Must be given as xsd:nonNegativeInteger.
///
[SammPropertyUri("bamm-c:minValue")]
- public uint? MinValue;
+ public uint? MinValue { get; set; }
}
///
@@ -548,14 +585,18 @@ public class LengthConstraint : Constraint
///
///
///
- public class RegularExpressionConstraint : Constraint
+ public class RegularExpressionConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-regular-expression-constraint";
+ public new string GetSelfUrn() => "bamm-c:RegularExpressionConstraint";
+
///
/// The regular expression.
///
///
[SammPropertyUri("bamm-c:value")]
- public string? Value;
+ public string? Value { get; set; }
}
///
@@ -564,15 +605,19 @@ public class RegularExpressionConstraint : Constraint
///
///
///
- public class FixedPointConstraint : Constraint
+ public class FixedPointConstraint : Constraint, ISammSelfDescription
{
+ // self description
+ public new string GetSelfName() => "samm-fixed-point-constraint";
+ public new string GetSelfUrn() => "bamm-c:FixedPointConstraint";
+
///
/// The scaling factor for a fixed point number. E.g., if a fixedpoint number is 123.04, the
/// scaling factor is 2 (the number of digits after the decimal point).
/// Must be given as xsd:positiveInteger.
///
[SammPropertyUri("bamm-c:scale")]
- public uint? Scale;
+ public uint? Scale { get; set; }
///
/// The number of integral digits for a fixed point number. E.g., if a fixedpoint number
@@ -580,7 +625,7 @@ public class FixedPointConstraint : Constraint
/// Must be given as xsd:positiveInteger.
///
[SammPropertyUri("bamm-c:integer")]
- public uint? Integer;
+ public uint? Integer { get; set; }
}
///
@@ -593,8 +638,6 @@ public class Characteristic : ModelElement, ISammSelfDescription, ISammStructure
{
// self description
public string GetSelfName() => "samm-characteristic";
- // public string GetSelfUrn() => "urn:bamm:io.openmanufacturing:characteristic:1.0.0#Characteristic";
- // FIX: seems to use bamm: instead of bamm-c: !!
public string GetSelfUrn() => "bamm:Characteristic";
// structure model
@@ -626,12 +669,23 @@ public Characteristic()
///
///
///
- public class Trait : Characteristic, ISammSelfDescription
+ public class Trait : Characteristic, ISammSelfDescription, ISammStructureModel
{
// self description
public new string GetSelfName() => "samm-trait";
public new string GetSelfUrn() => "bamm-c:Trait";
+ // structure model
+ public new bool IsTopElement() => false;
+ public new IEnumerable DescendOnce()
+ {
+ if (BaseCharacteristic != null)
+ yield return BaseCharacteristic;
+ if (Constraint != null)
+ foreach (var cn in Constraint)
+ yield return cn;
+ }
+
///
/// The Characterstic that is being constrained.
/// Identified via preferredName in any language
@@ -644,6 +698,7 @@ public class Trait : Characteristic, ISammSelfDescription
/// to add multiple Constraints to the base Characteristic.
///
[SammPropertyUri("bamm-c:constraint")]
+ [SammPropertyFlags("constraints")]
public List? Constraint { get; set; }
}
@@ -1135,12 +1190,25 @@ public static class Constants
typeof(StructuredValue)
};
+ public static Type[] AddableConstraints =
+ {
+ typeof(Constraint),
+ typeof(LanguageConstraint),
+ typeof(LocaleConstraint),
+ typeof(RangeConstraint),
+ typeof(EncodingConstraint),
+ typeof(LengthConstraint),
+ typeof(RegularExpressionConstraint),
+ typeof(FixedPointConstraint)
+ };
+
public static Type[] AddableElements =
{
// Top level
typeof(Aspect),
typeof(Property),
typeof(Entity),
+ typeof(Unit),
// Characteristic
typeof(Characteristic),
typeof(Trait),
@@ -1157,7 +1225,16 @@ public static class Constants
typeof(Code),
typeof(Either),
typeof(SingleEntity),
- typeof(StructuredValue)
+ typeof(StructuredValue),
+ // Constraints
+ typeof(Constraint),
+ typeof(LanguageConstraint),
+ typeof(LocaleConstraint),
+ typeof(RangeConstraint),
+ typeof(EncodingConstraint),
+ typeof(LengthConstraint),
+ typeof(RegularExpressionConstraint),
+ typeof(FixedPointConstraint)
};
///
@@ -1296,13 +1373,43 @@ static Constants()
Background = 0xFFB9AB50
});
- _renderInfo.Add(typeof(Constraint), new SammElementRenderInfo()
- {
- DisplayName = "Constraint",
- Abbreviation = "C",
- Foreground = 0xFF000000,
- Background = 0xFF74AEAF
- });
+ _renderInfo.Add(
+ types: new[] {
+ typeof(Constraint),
+ typeof(LanguageConstraint),
+ typeof(LocaleConstraint),
+ typeof(RangeConstraint),
+ typeof(EncodingConstraint),
+ typeof(LengthConstraint),
+ typeof(RegularExpressionConstraint),
+ typeof(FixedPointConstraint)
+ },
+ displayNames: new[] {
+ "Constraint",
+ "LanguageConstraint",
+ "LocaleConstraint",
+ "RangeConstraint",
+ "EncodingConstraint",
+ "LengthConstraint",
+ "RegularExpressionConstraint",
+ "FixedPointConstraint"
+ },
+ abbreviations: new[] {
+ "C",
+ "LGC",
+ "LOC",
+ "RGC",
+ "ENC",
+ "LNC",
+ "REC",
+ "FPC"
+ },
+ value: new SammElementRenderInfo() {
+ DisplayName = "Constraint",
+ Abbreviation = "C",
+ Foreground = 0xFF000000,
+ Background = 0xFF74AEAF
+ });
_renderInfo.Add(typeof(Trait), new SammElementRenderInfo()
{
diff --git a/src/AasxPackageLogic/DispEditHelperModules.cs b/src/AasxPackageLogic/DispEditHelperModules.cs
index e57e80b78..d2d0f8b20 100644
--- a/src/AasxPackageLogic/DispEditHelperModules.cs
+++ b/src/AasxPackageLogic/DispEditHelperModules.cs
@@ -32,6 +32,8 @@ This source code may use other Open Source software components (see LICENSE.txt)
using System.Runtime.Intrinsics.X86;
using Lucene.Net.Tartarus.Snowball.Ext;
using Lucene.Net.Util;
+using System.Runtime.Serialization;
+using J2N.Text;
namespace AasxPackageLogic
{
@@ -732,18 +734,18 @@ public void DisplayOrEditEntityHasEmbeddedSpecification(
// let the user control the number of references
this.AddActionPanel(
stack, "Spec. records:", repo: repo,
- superMenu: superMenu,
- ticketMenu: new AasxMenu()
- .AddAction("add-record", "Add record",
- "Adds a record for data specification reference and content.")
- .AddAction("add-iec61360", "Add IEC61360",
- "Adds a record initialized for IEC 61360 content.")
- .AddAction("auto-detect", "Auto detect content",
- "Auto dectects known data specification contents and sets valid references.")
- .AddAction("delete-last", "Delete last record",
- "Deletes last record (data specification reference and content)."),
- ticketAction: (buttonNdx, ticket) =>
- {
+ superMenu: superMenu,
+ ticketMenu: new AasxMenu()
+ .AddAction("add-record", "Add record",
+ "Adds a record for data specification reference and content.")
+ .AddAction("add-iec61360", "Add IEC61360",
+ "Adds a record initialized for IEC 61360 content.")
+ .AddAction("auto-detect", "Auto detect content",
+ "Auto dectects known data specification contents and sets valid references.")
+ .AddAction("delete-last", "Delete last record",
+ "Deletes last record (data specification reference and content)."),
+ ticketAction: (buttonNdx, ticket) =>
+ {
if (buttonNdx == 0)
hasDataSpecification.Add(
new Aas.EmbeddedDataSpecification(
@@ -2411,13 +2413,50 @@ public void DisplayOrEditEntityFileResource(AnyUiStackPanel stack,
}
- //
- //
- // SAMM
- //
- //
+ //
+ //
+ // SAMM
+ //
+ //
- public Type SammExtensionHelperSelectSammType(Type[] addableElements)
+ public class EnumHelperMemberInfo
+ {
+ public string MemberValue = "";
+ public object MemberInstance;
+ }
+
+ public static IEnumerable EnumHelperGetMemberInfo(Type underlyingType)
+ {
+ foreach (var enumMemberInfo in underlyingType.GetFields(BindingFlags.Public | BindingFlags.Static))
+ {
+ var enumInst = Activator.CreateInstance(underlyingType);
+
+ var enumMemberStrValue = enumMemberInfo.GetCustomAttribute();
+ if (enumMemberStrValue?.Value != null)
+ {
+ var ev = enumMemberInfo.GetValue(enumInst);
+
+ yield return new EnumHelperMemberInfo()
+ {
+ MemberValue = enumMemberStrValue?.Value,
+ MemberInstance = ev
+ };
+
+ //// how to get the enum value?
+ //// (bad) solution is to iterate over values and compare types ..
+ //foreach (var ev in Enum.GetValues(underlyingType))
+ // if (ev.GetType() == enumMemberInfo.FieldType)
+ // {
+ // yield return new EnumHelperMemberInfo() {
+ // MemberValue = enumMemberStrValue?.Value,
+ // MemberInstance = ev
+ // };
+ // }
+ }
+ }
+ }
+
+ public Type SammExtensionHelperSelectSammType(Type[] addableElements)
{
// create choices
var fol = new List();
@@ -2475,7 +2514,8 @@ public AnyUiLambdaActionBase SammExtensionHelperSammReferenceAction(
T sr,
Action setValue,
Func createInstance,
- string[] presetList = null) where T : SammReference
+ string[] presetList = null,
+ Type[] addableElements = null) where T : SammReference
{
if (actionIndex == 0 && presetList != null && presetList.Length > 0)
{
@@ -2508,7 +2548,9 @@ public AnyUiLambdaActionBase SammExtensionHelperSammReferenceAction(
if (actionIndex == 2)
{
// select type
- var sammTypeToCreate = SammExtensionHelperSelectSammType(Samm.Constants.AddableElements);
+ var sammTypeToCreate = SammExtensionHelperSelectSammType(
+ addableElements: (addableElements != null)
+ ? addableElements : Samm.Constants.AddableElements);
if (sammTypeToCreate == null)
return new AnyUiLambdaActionNone();
@@ -2606,7 +2648,8 @@ public void SammExtensionHelperAddSammReference(
bool noFirstColumnWidth = false,
string[] presetList = null,
bool showButtons = true,
- bool editOptionalFlag = false) where T : SammReference
+ bool editOptionalFlag = false,
+ Type[] addableElements = null) where T : SammReference
{
var grid = AddSmallGrid(1, 2, colWidths: new[] { "*", "#" });
stack.Add(grid);
@@ -2637,7 +2680,8 @@ public void SammExtensionHelperAddSammReference(
sr: sr,
setValue: setValue,
createInstance: createInstance,
- presetList: presetList);
+ presetList: presetList,
+ addableElements: addableElements);
});
if (editOptionalFlag && sr is OptionalSammReference osr)
@@ -2665,7 +2709,8 @@ public void SammExtensionHelperAddListOfSammReference(
List value,
Action> setValue,
Func createInstance,
- bool editOptionalFlag) where T : SammReference
+ bool editOptionalFlag,
+ Type[] addableElements = null) where T : SammReference
{
this.AddVerticalSpace(stack);
@@ -2681,7 +2726,7 @@ public void SammExtensionHelperAddListOfSammReference(
rows: 1 + value.Count, cols: 2,
minWidthFirstCol: GetWidth(FirstColumnWidth.Standard),
paddingCaption: new AnyUiThickness(5, 0, 0, 0),
- colWidths: new[] { "*", "#" });
+ colWidths: new[] { "*", "#" });
AnyUiUIElement.RegisterControl(
AddSmallButtonTo(sg, 0, 1,
@@ -2710,6 +2755,7 @@ public void SammExtensionHelperAddListOfSammReference(
noFirstColumnWidth: true,
showButtons: false,
editOptionalFlag: editOptionalFlag,
+ addableElements: addableElements,
setValue: (v) => {
value[theLsri] = v;
setValue?.Invoke(value);
@@ -2797,6 +2843,390 @@ public void SammExtensionHelperAddListOfSammReference(
}
+ public void SammExtensionHelperAddCompleteModelElement(
+ Aas.Environment env, AnyUiStackPanel stack,
+ Samm.ModelElement sammInst,
+ Aas.IReferable relatedReferable,
+ Action setValue)
+ {
+ // access
+ if (env == null || stack == null || sammInst == null)
+ return;
+
+ // visually ease
+ this.AddVerticalSpace(stack);
+
+ // okay, try to build up a edit field by reflection
+ var propInfo = sammInst.GetType().GetProperties();
+ for (int pi = 0; pi < propInfo.Length; pi++)
+ {
+ // access
+ var pii = propInfo[pi];
+
+ // some type investigation
+ var propType = pii.PropertyType;
+ var underlyingType = Nullable.GetUnderlyingType(propType);
+
+ // try to access flags
+ var propFlags = "" + pii.GetCustomAttribute()?.Flags;
+ var propFlagsLC = propFlags.ToLower();
+
+ // List of SammReference?
+ if (pii.PropertyType.IsAssignableTo(typeof(List)))
+ {
+ var addableElements = Samm.Constants.AddableElements;
+ if (propFlagsLC.Contains("contraints"))
+ addableElements = Samm.Constants.AddableConstraints;
+
+ SammExtensionHelperAddListOfSammReference(
+ env, stack, caption: "" + pii.Name,
+ (ModelElement)sammInst,
+ relatedReferable,
+ editOptionalFlag: false,
+ value: (List)pii.GetValue(sammInst),
+ setValue: (v) =>
+ {
+ pii.SetValue(sammInst, v);
+ setValue?.Invoke(sammInst);
+ },
+ createInstance: (sr) => new SammReference(sr));
+ }
+
+ // List of optional SammReference?
+ if (pii.PropertyType.IsAssignableTo(typeof(List)))
+ {
+ SammExtensionHelperAddListOfSammReference(
+ env, stack, caption: "" + pii.Name,
+ (ModelElement)sammInst,
+ relatedReferable,
+ editOptionalFlag: true,
+ value: (List)pii.GetValue(sammInst),
+ setValue: (v) =>
+ {
+ pii.SetValue(sammInst, v);
+ setValue?.Invoke(sammInst);
+ },
+ createInstance: (sr) => new OptionalSammReference(sr));
+ }
+
+ // NamespaceMap
+ if (pii.PropertyType.IsAssignableTo(typeof(Samm.NamespaceMap)))
+ {
+ this.AddVerticalSpace(stack);
+
+ var lsr = (Samm.NamespaceMap)pii.GetValue(sammInst);
+
+ Action lambdaSetValue = (v) =>
+ {
+ pii.SetValue(sammInst, v);
+ setValue?.Invoke(sammInst);
+ };
+
+ if (this.SafeguardAccess(stack, repo, lsr, "" + pii.Name + ":",
+ "Create data element!",
+ v =>
+ {
+ lambdaSetValue(new Samm.NamespaceMap());
+ return new AnyUiLambdaActionRedrawEntity();
+ }))
+ {
+ // Head
+ var sg = this.AddSubGrid(stack, "" + pii.Name + ":",
+ rows: 1 + lsr.Count(), cols: 3,
+ minWidthFirstCol: GetWidth(FirstColumnWidth.Standard),
+ paddingCaption: new AnyUiThickness(5, 0, 0, 0),
+ colWidths: new[] { "80:", "*", "#" });
+
+ AnyUiUIElement.RegisterControl(
+ AddSmallButtonTo(sg, 0, 2,
+ margin: new AnyUiThickness(2, 2, 2, 2),
+ padding: new AnyUiThickness(1, 0, 1, 0),
+ content: "\u2795"),
+ (v) =>
+ {
+ lsr.AddOrIgnore(":", "");
+ lambdaSetValue(lsr);
+ return new AnyUiLambdaActionRedrawEntity();
+ });
+
+ // individual references
+ for (int lsri = 0; lsri < lsr.Count(); lsri++)
+ {
+ var theLsri = lsri;
+
+ // prefix
+ AnyUiUIElement.RegisterControl(
+ AddSmallTextBoxTo(sg, 1 + theLsri, 0,
+ text: lsr[theLsri].Prefix,
+ margin: new AnyUiThickness(4, 2, 2, 2)),
+ (v) =>
+ {
+ lsr[theLsri].Prefix = (string)v;
+ pii.SetValue(sammInst, lsr);
+ setValue?.Invoke(sammInst);
+ return new AnyUiLambdaActionNone();
+ });
+
+ // uri
+ AnyUiUIElement.RegisterControl(
+ AddSmallTextBoxTo(sg, 1 + theLsri, 1,
+ text: lsr[theLsri].Uri,
+ margin: new AnyUiThickness(2, 2, 2, 2)),
+ (v) =>
+ {
+ lsr[theLsri].Uri = (string)v;
+ pii.SetValue(sammInst, lsr);
+ setValue?.Invoke(sammInst);
+ return new AnyUiLambdaActionNone();
+ });
+
+ // minus
+ AnyUiUIElement.RegisterControl(
+ AddSmallButtonTo(sg, 1 + theLsri, 2,
+ margin: new AnyUiThickness(2, 2, 2, 2),
+ padding: new AnyUiThickness(5, 0, 5, 0),
+ content: "-"),
+ (v) =>
+ {
+ lsr.RemoveAt(theLsri);
+ pii.SetValue(sammInst, lsr);
+ setValue?.Invoke(sammInst);
+ return new AnyUiLambdaActionRedrawEntity();
+ });
+ }
+ }
+ }
+
+ // List of Constraint?
+ if (pii.PropertyType.IsAssignableTo(typeof(List)))
+ {
+ ;
+ }
+
+ // single SammReference?
+ if (pii.PropertyType.IsAssignableTo(typeof(Samm.SammReference)))
+ {
+ this.AddVerticalSpace(stack);
+
+ var sr = (Samm.SammReference)pii.GetValue(sammInst);
+
+ // preset attribute
+ string[] presetValues = null;
+ var x3 = pii.GetCustomAttribute();
+ if (x3 != null)
+ {
+ presetValues = Samm.Constants.GetPresetsForListName(x3.PresetListName);
+ }
+
+ SammExtensionHelperAddSammReference(
+ env, stack, "" + pii.Name, (Samm.ModelElement)sammInst, relatedReferable,
+ sr,
+ presetList: presetValues,
+ setValue: (v) => {
+ pii.SetValue(sammInst, v);
+ setValue?.Invoke(sammInst);
+ },
+ createInstance: (sr) => new SammReference(sr));
+ }
+
+ // List of string?
+ if (pii.PropertyType.IsAssignableTo(typeof(List)))
+ {
+ this.AddVerticalSpace(stack);
+
+ var ls = (List)pii.GetValue(sammInst);
+ if (ls == null)
+ {
+ // Log.Singleton.Error("Internal error in SAMM element. Aborting.");
+ continue;
+ }
+
+ var sg = this.AddSubGrid(stack, "" + pii.Name + ":",
+ rows: 1 + ls.Count, cols: 2,
+ minWidthFirstCol: GetWidth(FirstColumnWidth.Standard),
+ paddingCaption: new AnyUiThickness(5, 0, 0, 0),
+ colWidths: new[] { "*", "#" });
+
+ AnyUiUIElement.RegisterControl(
+ AddSmallButtonTo(sg, 0, 1,
+ margin: new AnyUiThickness(2, 2, 2, 2),
+ padding: new AnyUiThickness(5, 0, 5, 0),
+ content: "Add blank"),
+ (v) =>
+ {
+ ls.Add("");
+ pii.SetValue(sammInst, ls);
+ setValue?.Invoke(sammInst);
+ return new AnyUiLambdaActionRedrawEntity();
+ });
+
+ for (int lsi = 0; lsi < ls.Count; lsi++)
+ {
+ var theLsi = lsi;
+ var tb = AnyUiUIElement.RegisterControl(
+ AddSmallTextBoxTo(sg, 1 + lsi, 0,
+ text: ls[lsi],
+ margin: new AnyUiThickness(2, 2, 2, 2)),
+ (v) =>
+ {
+ ls[theLsi] = (string)v;
+ pii.SetValue(sammInst, ls);
+ setValue?.Invoke(sammInst);
+ return new AnyUiLambdaActionRedrawEntity();
+ });
+
+ AnyUiUIElement.RegisterControl(
+ AddSmallButtonTo(sg, 1 + lsi, 1,
+ margin: new AnyUiThickness(2, 2, 2, 2),
+ padding: new AnyUiThickness(5, 0, 5, 0),
+ content: "-"),
+ (v) =>
+ {
+ ls.RemoveAt(theLsi);
+ pii.SetValue(sammInst, ls);
+ setValue?.Invoke(sammInst);
+ return new AnyUiLambdaActionRedrawEntity();
+ });
+ }
+ }
+
+ // single string?
+ if (pii.PropertyType.IsAssignableTo(typeof(string)))
+ {
+ var isMultiLineAttr = pii.GetCustomAttribute();
+
+ Func