1

The text of each buttons can change by the user and I want to analyze the button texts. I know I can put their texts in a string array but, since I want more properties, I want to put them in a List<Button>. But, the problem is that every time I change the text of one of the buttons in that list, the real button's text changes too.

How can I declare the list so that the original buttons aren't changed?

I've tested this:

Button bt1 = A1;
Button bt2 = (Button)bt1;
bt1.Text = "A";
bt2.Text = "B";

but the text of the button change to "B".

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Mohsen Nemati
  • 379
  • 1
  • 11

2 Answers2

1

The problem you are having is that Button is a class (i.e a reference type), hence, when you do this:

List<Button> list = new List<Button> { button1 };
list[0].Text = "A";

You are not modifying an object in the list, you are modifying button1 (because you added the reference to button1). If you don't want this to happen, you need to create copies of each button when you add them to the list.
You can use something like this to get it done:

List<Button> list = Controls
    .OfType<Button>()
    .Select(x => new Button
    {
        //copy the properties you want, for example:
        Text = x.Text,
        Name = x.Name
    })
    .ToList();

This way, since you are creating new instances for each Button, the references are not the same, so the original objects will remain intact. Of course, any change to the original object will not be reflected in these new objects.

If you don't want to use LINQ, you can use a more manual approach:

List<Button> list = new List<Button>();
list.Add(new Button { Text = btn1.Text, Name = btn1.Name, /* etc */ });
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
0

Put all 9 buttons in a parent control/view. Then, depending on the technology you're using, get all the child controls/views of that parent, call OfType<Button>() and make that into a list.

For example, in WinForms, this would be:

var listOfButtons = this.Controls.OfType<Button>().ToList();

EDIT: I just read your comment:

No my question is how to have a list of buttons and if you change the text of each button in the list, the real button's text doesn't change

Then you don't really need a list of buttons. You really just need a list of strings.

 var listOfButtonText = this.Controls.OfType<Button>()
    .Select(x => x.Text).ToList();

Then you can change the text however you like and it won't affect the actual button's text:

listOfButtonText[0] = "Foo";

I really see no benefit of using a new instance of a button here. Buttons are supposed to be displayed. Creating new buttons just to mess around with their Text is kind of a waste. I strongly recommend you using list of strings unless you've got a really good reason.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I want to know more properties of those buttons like names etc. so I prefer to have a list of buttons that if you change the properties, the real buttons won't change – Mohsen Nemati Jan 07 '18 at 15:24
  • @MohsenNemati I have never seen such a use case before. This begins to sound like an XY problem. Can you tell me more about what you want to do with your buttons? – Sweeper Jan 07 '18 at 15:26
  • @Sweeper See my answer for what the OP intended to do. It's not so uncommon in desktop development (I have a similar use case in WPF with elements of a ListView) – Camilo Terevinto Jan 07 '18 at 15:30
  • @Sweeper See Camilo Terevinto's answer. That's exactly what I mean – Mohsen Nemati Jan 07 '18 at 15:42