How to exclude some enum values in System.CommandLine? - c#

I have a System.CommandLine option like this (LogLevel is an enum):
private static readonly Option<LogLevel> option = new(new[] { "--logLevel" })
{
Description = "The severity (log level)."
};
The automatically generated help lists all the enum values as valid values for "--logLevel":
<Debug|Detailed|Error|Fatal|Info|Off|Silent|Warning>
But is it somehow possible to disallow some of them with System.CommandLine or even map strings on enum values (e.g. "W" is mapped to the enum value Warning)?

I found an answer in the Microsoft documentations:
It works like this:
var parser = new CommandLineBuilder(rootCommand)
.UseDefaults()
.UseHelp(ctx =>
{
ctx.HelpBuilder.CustomizeSymbol(foregroundColorOption,
firstColumnText: "--color <Black, White, Red, or Yellow>",
secondColumnText: "Specifies the foreground color. " +
"Choose a color that provides enough contrast " +
"with the background color. " +
"For example, a yellow foreground can't be read " +
"against a light mode background.");
})
.Build();
await parser.InvokeAsync(args);
foregroundColorOption is in this case the option and via firstColumnText, we can print whatever values of the enum we want to print.

Related

zpl what's the difference between 200dpi and 300dpi?

I have a question. I'm new to ZPL language I used zebra designer to create a label in 200dpi. If I want to make the same label but in 300dpi. What does it change in my zpl code exactly? I was thinking of the dimension, like in
^LL799
799 will change to another size, but is there anything else?
EDIT:
My goal is to create a C# application to print label on my zebra printers.
The user will choose if it's a 200dpi or a 300dpi and then the right code is sent to GenericText/Only to print on my printer (print to GenericText/Only is required I can't change that). So if you know a way to do that in C# I take it too.
Thanks in advance
To switch resolution, the ZPL template needs to change in order for the label to be printed correctly. Basically it's just a matter of scaling by 3/2 for most fields. For example:
200dpi 300dpi
-------- --------
^FO40,40 -> ^FO60,60
^BY4 -> ^BY6
And so on. I coded a converted that does the opposite, just change the multiplier from 2/3 to 3/2 and you should be good to go:
public static void Main()
{
var evaluator = new MatchEvaluator(Converter);
const string pattern = #"(?<=\^[A-Z0-9]{2,3},?)([0-9]+,[0-9]+)";
const string input = #" ... ZPL CODE HERE";
Console.WriteLine(Regex.Replace(input, pattern, evaluator));
Console.WriteLine();
Console.WriteLine("Press any key to quit...");
Console.ReadKey();
}
public static string Converter(Match match)
{
var (w, h) = (double.Parse(match.Value.Split(',')[0]), double.Parse(match.Value.Split(',')[1]));
var (wNew, hNew) = ((int)Math.Floor(w * 2 / 3), (int)Math.Floor(h * 2 / 3));
return wNew + "," + hNew;
}
This will not convert some fields, such as barcodes. You need to change those manually. You should use http://labelary.com/viewer.html to check the results and adapt. Open 2 viewers and paste 203 and 300 dpi, then select the resolution and label size and compare.

How do I change Color of Label by getting the Color from another Label?

I am trying to do something similar to the one in the example but changing the colour of the text/label.
Example:
Label1.Text = Label2.Text;
Label2.Text = Label3.Text;
Label3.Text = Label4.Text;
//so and and so forth
I am looking for a very simple solution like the one shown in the example but with colors.
I am using Windows Form App with .Net Framework 4.7.2, I am using C# 9.0.
I have tried using .ForceColor as a way to change the color but as you can see, i am trying to accomplish a similar thing as the one in the example.
At first, I suggest put labels in a container, And don't put anything except labels.
Then:
Do for loop, and length = ContainerPanel.Controls.Count - 1, with condition i = ContainerPanel.Controls.Count
Cast Control[i] to labelFirst
Cast Control[i + 1] to labelSecond
labelFirst.ForeColor = labelSecond.ForeColor
In this example, Container is: ContainerPanel
for (int i = 0; i < ContainerPanel.Controls.Count - 1; i++)
{
// This is a simple way without variables
(Label(ContainerPanel.Controls[i])).ForeColor = (Label(ContainerPanel.Controls[i + 1]));
}
Note: last Label You should change its ForeColor, Or it will not be changed.
Q&A
Q: Why length = ContainerPanel.Controls.Count - 1??
A: Because we should get Cast Control[i + 1] to labelSecond, And we can't, except if the length is less than controls count by one

Office.Interop.Word and Lists with SubLevels

I've been scouring the interwebs for documentation leading me to be able to create lists. In doing so, I've not really been able to find any documentation that will allow me to create `lists within lists.
I've tried using the built-in macro recorder, but for whatever reason, it behaves differently when recording vs. when not recording (e.g. when I create a list item, and hit enter + tab, it doesn't create a sub list).
I've found "The Wordmeister's" MSDN post which helped me get to making a list, but lists within lists doesn't work so well for me.
Word.Paragraph p2 = doc.Paragraphs.Add();
Word.Range p2rng = p2.Range;
object oTrue = true;
object oFalse = false;
object oListName = "TreeList";
Word.ListTemplate lstTemp = doc.ListTemplates.Add(ref oTrue, ref oListName);
int l;
p2rng.ParagraphFormat.TabIndent(1);
p2rng.Text = "Rates:\r\nLevel 1\rLevel 1.1\rLevel 1.2\rLevel 2\rLevel 2.1\rLevel 2.1.1";
l = 1;
lstTemp.ListLevels[l].NumberFormat = "%" + l.ToString() + ".";
lstTemp.ListLevels[l].NumberStyle = Word.WdListNumberStyle.wdListNumberStyleArabic;
lstTemp.ListLevels[l].NumberPosition = wordApp.CentimetersToPoints(0.5f * (l - 1));
lstTemp.ListLevels[l].TextPosition = wordApp.CentimetersToPoints(0.5f * l);
l = 2;
lstTemp.ListLevels[l].NumberFormat = "%" + (l - 1).ToString() + ".%" + l.ToString() + ".";
lstTemp.ListLevels[l].NumberStyle = Word.WdListNumberStyle.wdListNumberStyleArabic;
lstTemp.ListLevels[l].NumberPosition = wordApp.CentimetersToPoints(0.5f * (l - 1));
lstTemp.ListLevels[l].TextPosition = wordApp.CentimetersToPoints(0.5f * l);
l = 3;
lstTemp.ListLevels[l].NumberFormat = "%" + (l - 2).ToString() + "%" + (l - 1).ToString() + ".%" + l.ToString() + ".";
lstTemp.ListLevels[l].NumberStyle = Word.WdListNumberStyle.wdListNumberStyleArabic;
lstTemp.ListLevels[l].NumberPosition = wordApp.CentimetersToPoints(0.5f * (l - 1));
lstTemp.ListLevels[l].TextPosition = wordApp.CentimetersToPoints(0.5f * l);
object oListApplyTo = Word.WdListApplyTo.wdListApplyToWholeList;
object oListBehavior = Word.WdDefaultListBehavior.wdWord10ListBehavior;
p2rng.ListFormat.ApplyListTemplate(lstTemp, ref oFalse, ref oListApplyTo, ref oListBehavior);
All credit to Cindy Meister for this code, it is only slightly modified to work for my use case.
The above results in the following:
Basically, how do you create multi level lists (like the following image) with lists within lists?
It's not really possible to create a "list within a list" in Word.
What you can do is put static text in the list level, in front of the dynamic number. This is the same idea as using "Chapter" or "Section" in front of the level's number, except in this case it should be a bullet symbol.
The place to define this, based on the code sample in the question, is:
lstTemp.ListLevels[l].NumberFormat = "%" + l.ToString() + ".";
As part of the NumberFormat string, in other words. For symobls this will require a conversion from unicode hex or decimal to the String data type. For example, for a solid, round bullet and an outline, round bullet for levels 1 and 2, respectively (hard-coding the list level for purposes of clarity):
char Symbol1 = (char)9679;
char Symbol2 = (char)9675;
lstTemp.ListLevels[1].NumberFormat = Symbol1.ToString() + "\t%" + l.ToString() + ".";
lstTemp.ListLevels[2].NumberFormat = Symbol2.ToString() + "\t%" + 2.ToString() + ".";
Lets try providing an answer that doesn't get deleted.
The updated list within lists example provided by #Jaberwocky can be achieved using the technique I explained in a previous post.
MS-Word: Cross reference to custom reference type
To apply the above to the specific instance required by #Jaberwock we need to amend the number formats of the list templates to which styles are linked. I'll use Word to set up the styles and required multilevel list and then include a short VBA macro which shows how to amend the list number format.
In line with the link above we first need to create our styles. The emulate the list within list example above we need to define two styles. I've defined 'ListWithinList 1' and 'ListWithinList 2'.
The key settings for these two styles are to set the outline level as 1 and 2 respectively, and to set appropriate tab stops. I've used tabs at 1,2,3 and 4 cm. Add some text to a word document and apply the styles. I've included the navigation pane in the picture below so that we can see the indentation due to the outline level of the styles
The next step is to define the multilevel list and link each level to the relevant style
Settings for outline level 1
settings for outline level 2
Our text now looks like this
I've used Word up to this point to avoid the tediousness of setting up styles and list templates programatically.
Let's now modify the format of the list numbering using a snippet of VBA.
Option Explicit
Public Sub AddTextToListNumber()
Dim my_prefix(1 To 2) As String
Dim my_index As Long
my_prefix(1) = ChrW(&H25AA) & vbTab ' small black square
my_prefix(2) = ChrW(&H25AB) & vbTab ' small white square
For my_index = 1 To 2
With ActiveDocument.Styles("ListWithinList " & CStr(my_index)).ListTemplate.ListLevels(my_index)
.numberformat = my_prefix(my_index) & .numberformat
End With
Next
End Sub
If we run the code above then the text in our document becomes
Which looks a bit ugly because of the 1cm tab stops.
If there is anything that isn't clear above please add a comment and if possible I'll update the answer.
NOTE: We didn't need the VBA code to complete setting up the list formats as we could have used appropriate Alt+XXXX keyboard sequences to insert the characters in the number format box of the multilevel list dialog box.

Is it possible to assign color to a C# TextBox based on a SQL table with that information?

The following code reads perfectly the values I am looking to fill in textboxes and compare for other calculations. But, at the same time, one of them, the getColorFromTable = dataReader["ReqCol"].ToString(); returns the colorof the device being calculated. I am trying to find a way that the application reads the same color from the table and assign it to the following:
txPaintColorUpdate.ForeColor and txPaintColorUpdate.BorderColor
So, there are four colors in the table: Red, Orange, Green and Light Blue. After the calculation occurs, the system assigns the type of color to the device, but as an indicator, should change the color of txPaintColorUpdate as mentioned above.
Here is a portion of code:
conn.Open();
SqlDataReader dataReader;
dataReader = cmd.ExecuteReader();
if (dataReader.Read())
{
minimumFlowCapacity = dataReader["MinFC"].ToString();
maximumFlowCapacity = dataReader["MaxFC"].ToString();
getColorFromTable = dataReader["ReqCol"].ToString();
getClassification = dataReader["Class"].ToString();
}
Thus, variable getColorFromTable is receiving the name of the color from the table and displaying it in the TextBox (txPaintColorUpdate). Any advice how to read the same color name so C# can assign it to the TextBox? I know that the common way to do that is invoking txPaintColorUpdate.BorderColor = System.Drawing.Color.Red; and txPaintColorUpdate.ForeColor = System.Drawing.Color.Orange;, but maybe there is an easier way without doing a lot of if() else{} statements.
This is a portion of code of when the calculation is made and should assign the color to the TextBox:
if (flow20PSI >= Convert.ToDouble(minimumFlowCapacity) && flow20PSI <= Convert.ToDouble(maximumFlowCapacity))
{
txPaintColorUpdate.Text = getColorFromTable;
//txPaintColorUpdate.ForeColor = System.Drawing.Color(txPaintColorUpdate.);
//txPaintColorUpdate.BorderColor = System.Drawing.Color.Red;
}
Thanks #Etienne, your solution led me to find the one I needed using this:
public static Color FromName(string colorName)
{
System.Drawing.Color systemColor = System.Drawing.Color.FromName(colorName);
return new Color(systemColor.R, systemColor.G, systemColor.B, systemColor.A); //Here Color is Microsoft.Xna.Framework.Graphics.Color
}
From: Convert string to Color in C#
My solution was only using this: System.Drawing.Color systemColor = System.Drawing.Color.FromName(getColorFromTable);

Parsing multiple enum values (Flagged): Reading in a filter type from a query string

I'm plan to make a page that displays info about user's in the form of a table. Each column will be a property of the table. I want someone viewing the table to be able to choose ways to filter the users. There will be two check boxes: 1 for reported users and 1 for creation date. I'm planning to make an enum called UserFilter like so:
public enum UserFilter
{
None = 0,
Date = 1,
Reported = 2
}
If I need to add another type it's value will be set to 4 so that I can tell which enums are selected through a bitwise or (3 would be both 1 and 2). The problem I'm having is with reading in an enum from the query string. I guess I could do something like posting back with an int (0 for none, 1 for date, 2 for report, 3 for both) but I would like to try posting back with the actual string. I'm not sure how I would parse "Date|Reported" into an enum value that doesn't exist in UserFilter.
In a nutshell: Is there a clean way to parse "Date|Reported" into the value 3 without adding another value to my enum?
You could try something like
string enumString = "Date|Reported";
UserFilter uf = enumString.Split('|').ToList().Select(e =>
{
UserFilter u;
Enum.TryParse(e, true, out u);
return u;
}).Aggregate((u, c) => u = u | c);
I would however recomend that you change your enum to
public enum UserFilter
{
None = 1,
Date = 2,
Reported = 4
}
as if you have it your way None|Date is the same as Date, because 0 + 1 => 1
EDIT
As #ScottSelby stated, this would also work
UserFilter u = (UserFilter) 3;
//or 6 rather than 3 if you take my comment above into consideration

Categories