Есть ли способ динамически генерировать код для взаимодействия с кнопками в C#? - PullRequest
1 голос
/ 24 февраля 2020

Я пытаюсь найти способ, позволяющий по существу динамически генерировать код на основе ввода.

Например, я мог бы напечатать что-то вроде:

int Number = 22;
Button<Number>.Text = "X";

Так что в этом В этом случае для кнопки 22 будет установлен текст «X».

И я мог бы изменить его так, чтобы я мог ввести, например, 24 в программу, а затем для кнопки 24 установить значение «X». вместо того, чтобы устанавливать кучу операторов if для покрытия каждой потенциальной кнопки, нажмите.

Для дальнейшего контекста у меня есть Grid из 64 кнопок, и мне нужно иметь возможность редактировать их индивидуально, чтобы показать пользователю, какие кнопки Вы можете сделать это с помощью множества операторов if, но я подумал, что, возможно, стоит попытаться найти более элегантное решение.

Ответы [ 3 ]

1 голос
/ 24 февраля 2020

У вас может быть список кнопок:

private List<Button> _buttons = new List<Button>();

Заполните его так:

    for (int i = 0; i < 10; i++)
    {
        var b = new Button();
        b.Text = $"Button #{i}";
        b.Click += HandleButtonClick;
    }

И вы даже можете установить обработчик события для одного из его событий, которое не ' даже не нужно использовать список (sender является источником события):

private void HandleButtonClick(object sender, EventArgs e)
{
    (sender as Button).Text = "X";
}
1 голос
/ 24 февраля 2020

Кнопки имеют свойство Tag, которое можно использовать для хранения произвольных данных о кнопке, это описано для WinForms , WPF и UWP . Простое использование, аналогичное требованию OP, продемонстрировано в этой публикации SO

Эта ситуация в практическом смысле является самой причиной того, что .Tag вообще существует в элементах управления пользовательского интерфейса в значительной степени от рождение c#.

Таким образом, вам не нужно использовать пользовательский класс для кнопки, просто присвойте свое значение свойству .Tag класса Button, который вы создаете программно:

в этом примере список используется для создания кнопок и отделения создания от макета, в этом нет необходимости, но это может быть полезно. Вместо этого вы можете назначить эту кнопку его родительскому контейнеру и / или установить поля или координаты макета, вообще не сохраняя ссылку на объект Button.
Если OP обновляет сообщение для включения примеров реализации, мы можем обновить это ответ с более точным c и полным кодом.


private List<Button> _buttons = new List<Button>();
// ... iteration or switching logic 
var nextButton = new Button 
{ 
    Text = "x",
    Tag = 22
};
nextButton.Click += DynamicButton_Click;
_buttons.Add(nextButton);

// ... later push the buttons into the parent container or bind to the UI

Затем обработчик нажатия кнопки, вы можете получить доступ к этому свойству тега:

это представлено из WinForms, единственная разница в UWP или WPF - это сигнатура метода, измените EventArgs на RoutedEventArgs


private void DynamicButton_Click(object sender, EventArgs e)
{
    if(int.TryParse((sender as Button).Tag?.ToString(), out int buttonValue))
    {
        // use buttonValue
        Console.Out.WriteLine(buttonValue);
    }
    else
    {
        // Otherwise, sender was not a button, or the button did not have an integer tag value
        // either way, handle that error state here...
    }
}

Используя эти концепции, как только кнопки будут созданы, скажем, в некотором простом выравнивании сетки, Вы можете позволить пользователю установить это значение Tag во время выполнения, если у вас есть поле ввода TextBox (или другое), к которому можно получить доступ из кода.

Я рекомендую использовать для этого привязки стиля MVVM, а не прямые ссылки на элемент управления TextBox, но это просто для демонстрации сути.


private void DynamicButton_Click(object sender, EventArgs e)
{
    // assign the string value from the ButtonValueTextbox control to this button
    string value = this.ButtonValueTextBox.Text;
    if(sender is Button button)
    {
        button.Tag = value;
    }
    else
    {
        // Otherwise, sender was not a button
        // handle the error state here if you need to...
    }
}

Теперь, когда каждая кнопка имеет тег, вы можете легко добавить logi c для сохранения уникальных значений тега, перебирая другие кнопки и очищая тег, если он был ранее назначен другой кнопке.

0 голосов
/ 24 февраля 2020

Может быть, вы могли бы сохранить List из Button References:

var myButtons = new List<Button>();
myButtons.Add(firstButton);
myButtons.Add(secondButton);

// ... etc

// ... then somewhere else 

int number = 3;
myButtons[number].Text = "xxx";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...