C
C#2y ago
?

Double check if an object is one of provided types

Is there a way to quickly check that? I mean a can be either TextBox or CheckBox, doesn't matter which one, I want this condition to success if one of these
44 Replies
?
?OP2y ago
void OnLoad(object? sender, EventArgs e)
{
foreach(var a in Controls)
{
if(a is TextBox temp)
{
temp.BackColor = Color.Black;
temp.ForeColor = Color.Silver;
}
}
}
void OnLoad(object? sender, EventArgs e)
{
foreach(var a in Controls)
{
if(a is TextBox temp)
{
temp.BackColor = Color.Black;
temp.ForeColor = Color.Silver;
}
}
}
Here is where I use it
Angius
Angius2y ago
temp cannot be one of two types Algebraic data types are not a thing in C#
?
?OP2y ago
Oh, right!
Angius
Angius2y ago
Or you could maybe do a is { BackColor: _, ForeColor: _ } But that won't allow for a cast either
?
?OP2y ago
void OnLoad(object? sender, EventArgs e)
{
foreach(var a in Controls)
{
if(a is TextBox temp )
{
temp.BackColor = Color.Black;
temp.ForeColor = Color.Silver;
}

if(a is CheckBox temp1) // will have to copy paste this for each type
{
temp1.BackColor = Color.Black;
temp1.ForeColor = Color.Silver;
}
}
}
void OnLoad(object? sender, EventArgs e)
{
foreach(var a in Controls)
{
if(a is TextBox temp )
{
temp.BackColor = Color.Black;
temp.ForeColor = Color.Silver;
}

if(a is CheckBox temp1) // will have to copy paste this for each type
{
temp1.BackColor = Color.Black;
temp1.ForeColor = Color.Silver;
}
}
}
As I check they don't have any common class that they derive from so I guess I'll have to create an if for each type e.g. if(a is Button temp2) then if(a is MenuItem temp3) and so on...
?
?OP2y ago
This doesn't seem to work and this also not
Angius
Angius2y ago
x is {A, B} checks if x is of type that has properties A and B
?
?OP2y ago
Yeah but that's going to affect probably entire form as everything here derives from Control class (Windows Forms) I rather wanted to specify to which particular classes I want to compare with
?
?OP2y ago
It fails, needs a cast probably
Thinker
Thinker2y ago
Just do
if (a is TextBox t)
{
t.BackColor = Color.Black;
t.ForeColor = Color.Silver;
}
if (a is CheckBox b)
{
b.BackColor = Color.Black;
b.ForeColor = Color.Silver;
}
if (a is TextBox t)
{
t.BackColor = Color.Black;
t.ForeColor = Color.Silver;
}
if (a is CheckBox b)
{
b.BackColor = Color.Black;
b.ForeColor = Color.Silver;
}
Easiest way without any nonsense
?
?OP2y ago
Yeah, this is the only option that comes to my mind but I didn't want that "naive" approach to copy paste bunch of lines that is the same inside each if statement
Thinker
Thinker2y ago
You could use a switch
?
?OP2y ago
That seemed like a great idea but also fails
?
?OP2y ago
I already have it
Thinker
Thinker2y ago
Btw, OfType<Control> and not Cast<Control>
?
?OP2y ago
What do you mean?
Thinker
Thinker2y ago
stare doesn't even implement IEnumerable??
?
?OP2y ago
Yeah, these are the only options probably
Thinker
Thinker2y ago
(OfType is slightly better than Cast) Afaik it sometimes fails in weird places because it can't cast OfType also makes sure everything actually is of the type, which is especially relevant with non-generic collections
?
?OP2y ago
MODiX
MODiX2y ago
thinker227#5176
REPL Result: Success
var xs = new object[] {"a","b","c"};
(xs.Cast<string>(), xs.OfType<string>())
var xs = new object[] {"a","b","c"};
(xs.Cast<string>(), xs.OfType<string>())
Result: ValueTuple<IEnumerable<string>, IEnumerable<string>>
{
"item1": [
"a",
"b",
"c"
],
"item2": [
"a",
"b",
"c"
]
}
{
"item1": [
"a",
"b",
"c"
],
"item2": [
"a",
"b",
"c"
]
}
Compile: 508.973ms | Execution: 35.374ms | React with ❌ to remove this embed.
?
?OP2y ago
Uhm... so there is no way to do that?
ero
ero2y ago
Why not just...
foreach (Control control in Controls)
{

}
foreach (Control control in Controls)
{

}
...? Can't believe no one has suggested this... It's a collection of controls nonetheless
?
?OP2y ago
Wow, great, that seems to be really working...
ero
ero2y ago
It doesn't need to be generic
?
?OP2y ago
But I want to distinguish only certain control types that all derive from Control for example TextBox or CheckBox
ero
ero2y ago
You can then do if (control is TextBox or CheckBox or ...) and do your control.ForeColor anyway
?
?OP2y ago
And the original variable has type object @Ero so it is unknown what type it is I tried that and I can't
?
?OP2y ago
?
?OP2y ago
Hm that's also some solution 🤔 But what if an object is neither of Control type? 😄 The app might crash
?
?OP2y ago
Actually that didn't work in my case
ero
ero2y ago
That's why you specify the type in he loop head
?
?OP2y ago
But if I put there Controls I will not use sender variable at all, right?
ero
ero2y ago
It entirely depends on what you want this event to do Nevermind the fact that this is a pretty bad way to set the styling for controls You should be setting this in a resource dictionary and access the colors from there, at least for xaml based GUI frameworks
?
?OP2y ago
Let's say I have 30 text buttons in a form, how do I setup the same back and fore color for them all without doing that one by one?
ero
ero2y ago
I'm not sure if WinForms has a similar thing By doing it one by one, the correct way
?
?OP2y ago
nervousowo
ACiDCA7
ACiDCA72y ago
ive got no clue about winforms but i hope there is a way to use reusable styles, right? right???
ero
ero2y ago
That way allows you to add theming much easier As in, light and dark themes You bind the colors to a resource, and just change the resource
?
?OP2y ago
I think it exists but not for all controls Hmm thank you all for your help I honestly didn't expect so much attention and how active will become here pepetense I'll try playing with that, I guess there must be some way 😄
ero
ero2y ago
But yeah if you're planning on putting this event on multiple controls instead of putting a loop into it, then you don't have many choices i think
?
?OP2y ago
I thought about putting an event on the form to execute it after it loads Hmm to find all controls of a particular type and change their colors
ero
ero2y ago
if (sender is not (TextBox or CheckBox or Button))
return;

Control ctrl = (Control)sender;

// ...
if (sender is not (TextBox or CheckBox or Button))
return;

Control ctrl = (Control)sender;

// ...
Or an array of types, then types.Contains(sender.GetType())... But that's pretty ugly imo...
?
?OP2y ago
public ServerProviderForm()
{
InitializeComponent();

foreach(var control in Controls.Cast<Control>().Where(x => x is CheckBox or Button or TextBox))
{
control.BackColor = Color.Red;
control.ForeColor = Color.Blue;
}
}
public ServerProviderForm()
{
InitializeComponent();

foreach(var control in Controls.Cast<Control>().Where(x => x is CheckBox or Button or TextBox))
{
control.BackColor = Color.Red;
control.ForeColor = Color.Blue;
}
}
Aight, so actually that code worked. And I did a mistake by trying to put that in some OnEvent method, the easiest way was to put that in the form constructor method and use Controls property so right after the initialization selected controls of the specified class (CheckBox, Button, TextBox in my example) received Fore and Back color as I specified. Thank you @calledude if I saw correctly that was probably your idea do use .Cast<Control>().Where() Also thank you @Ero#1111@ACiDCA7#8219@thinker227#5176@Angius#1586 I can't ping you because I got timed out I haven't seen such engagement before catpog
Want results from more Discord servers?
Add your server