Повторяющийся код меня сводит с ума!

Хорошо, сначала я должен сказать, что все, что я знаю о кодировании, которое я узнал самостоятельно в свое свободное время, так что несите меня, если мой код примитивен, но, пожалуйста, я открыт для любых комментариев, чтобы сделать меня лучше. ..

В любом случае, что касается моего вопроса. У меня есть приложение, которое я создаю в C # для .NET Compact Framework (для HP iPaq), цель программы - действовать аналогично терминалу POS ресторана, чтобы «позвонить» заказам на еду. он дошел до такой степени, что некоторые из моих кодов - это одна и та же строка, скопированная богом, даже знает, сколько раз только с численным различием между ними. вот пример:

    private void button9_Click(object sender, EventArgs e)
    {
        AddItem(buttonNames[0], prices[0]);
    }

    private void button14_Click(object sender, EventArgs e)
    {
        AddItem(buttonNames[1], prices[1]);
    }

    private void button5_Click(object sender, EventArgs e)
    {
        AddItem(buttonNames[2], prices[2]);
    }


    private void button10_Click(object sender, EventArgs e)
    {
        AddItem(buttonNames[3], prices[3]);
    }

    private void button13_Click(object sender, EventArgs e)
    {
        AddItem(buttonNames[4], prices[4]);
    }

    private void button4_Click(object sender, EventArgs e)
    {
        AddItem(buttonNames[5], prices[5]);
    }

или

                button9.Text = buttonNames[0];
                button14.Text = buttonNames[1];
                button5.Text = buttonNames[2];
                button10.Text = buttonNames[3];
                button13.Text = buttonNames[4];
                button4.Text = buttonNames[5];
                button11.Text = buttonNames[6];
                button15.Text = buttonNames[7];
                button7.Text = buttonNames[8];
                button12.Text = buttonNames[9];
                button16.Text = buttonNames[10];
                button8.Text = buttonNames[11];

Я ЗНАЮ, что есть более простые способы сделать много кода, который я написал, я просто не знаю, как это сделать.

11 голосов | спросил Michael 13 J0000006Europe/Moscow 2013, 10:50:45

5 ответов


15

Несмотря на то, что разница минимальна, есть разница. Поэтому вам нужно сделать минимальное различие, в зависимости от нажатой кнопки.

Что вы можете сделать, так это создать общее событие для всех кнопок, и в этом случае вы определите индекс, который будет передан в AddItem(). Код может выглядеть так:

private void ButtonClick(object sender, EventArgs e)
{
    Button b = (Button)sender;

    switch(b.Name)
    {
        case "button9" : AddItem(buttonNames[0], prices[0]); break;
        case "button14" : AddItem(buttonNames[1], prices[1]); break;
        case "button5" : AddItem(buttonNames[2], prices[2]); break;
        //other buttons...
    }
}

Еще одно решение - предварительно присвоить индексу свойству Tag вашей кнопки:

button9.Text = buttonNames[0];
button9.Tag = 0;
//Same for other buttons

Таким образом вы также можете использовать общий метод, как и раньше, и использовать тег для вызова метода AddItem(). Вот так:

private void ButtonClick(object sender, EventArgs e)
{
    Button b = (Button)sender;
    int index = Convert.ToInt32(b.Tag);
    AddItem(buttonNames[index], prices[index]);
}

Наконец, если вы назовете свои кнопки по-другому, это станет еще проще сделать. Поместите индекс, который будет использоваться в названии кнопки, и получите его от имени в общем случае. Пример:

//Assignment of the buttons:
button0.Text = buttonNames[0];
button1.Text = buttonNames[1];
button2.Text = buttonNames[2];

//Event:
private void ButtonClick(object sender, EventArgs e)
{
    Button b = (Button)sender;
    int index = Convert.ToInt32(b.Name.Replace("button", ""));
    AddItem(buttonNames[index], prices[index]);
}

Надеюсь, это поможет!

ответил Abbas 13 J0000006Europe/Moscow 2013, 11:39:37
6

Очистите свои имена

button9.Text = buttonNames[0]; должен быть button0.Text = buttonNames[0]; Это также относится к вашему ценовому массиву.

Один метод обработчика событий

Создайте один обработчик событий, который подписан на каждой кнопке OnClick, и этот метод должен разобрать имя отправителя и посмотреть индекс кнопки , Если вы можете прочитать номер индекса (из приведенного выше примера 0), вы можете сказать:

AddItem(buttonNames[parsedIndex], prices[parsedIndex]);
ответил Peter Kiss 13 J0000006Europe/Moscow 2013, 11:30:21
3

Если вы можете, я думаю, лучшим решением было бы создать эти кнопки из кода (что BTW гораздо проще сделать в WPF благодаря панелям, привязке и шаблонам). Что-то вроде:

for (int i = 0; i < 6; i++)
{
    var button = new Button();
    // set the position of the button based on i here
    int iCopy = i; // to make closure work correctly
    button.Click += (s, e) => AddItem(buttonNames[iCopy], prices[iCopy]);
    this.Controls.Add(button); // assumes this is a Form
}

Кроме того, наличие двух массивов с синхронизированными индексами является запахом кода. Вероятно, у вас должен быть только один массив, содержащий объекты со свойствами ButtonName и Price. Тогда вы можете сделать только AddItem(items[iCopy]).

ответил svick 13 J0000006Europe/Moscow 2013, 19:51:12
2

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

Здесь мы используем объект для представления элемента питания вместо 2 массивов

public class FoodItem
{
    public String Name { get; set; }
    public double Price { get; set; }
    public override string ToString()
    {
        return Name + "@" + Price;
    }
}

Затем мы используем fooditem на карте с кнопками

    //Some setup in order to get our buttons all situated. 
    private void Form1_Load(object sender, EventArgs e)
    {
        FillButtonMap(); //First load the button map
        SetupButtons(); //Then register the click events to the proper additem call
    }

    public Dictionary<Button, FoodItem> ButtonMap = new Dictionary<Button, FoodItem>();
    //Here is where you add more buttons.
    void FillButtonMap()
    {
        ButtonMap.Add(button1, new FoodItem() { Name = "Taco", Price = 1.0 });
        ButtonMap.Add(button2, new FoodItem() { Name = "Burrito", Price = 2.0 });
        ButtonMap.Add(button3, new FoodItem() { Name = "Tostada", Price = 3.5 });
    }

    //This part sets the button text properly and registers the click event 
    //of the button to add the item 
    void SetupButtons()
    {
        foreach (var button in ButtonMap.Keys)
        {
            button.Text = ButtonMap[button].Name; //Set the button text
            var mappedFoodItem = ButtonMap[button]; //get the food item for the button 
            button.Click += (s, o) => { AddItem(mappedFoodItem); }; //Set the click event
        }
    }

    //Change AddItem to accept a FoodItem instead of String,Number
    void AddItem(FoodItem item)
    { //  Your Code Here...      }

Чтобы добавить Salsa, вы просто добавляете эту строку в FillButtonMap ...

    ButtonMap.Add(button4, new FoodItem() { Name = "Salsa", Price = 0.25 });

Чтобы сделать это более гибким, вы фактически переместите FillButtonMap во внешний файл, не статически подключая их к кнопкам, чтобы добавить больше элементов меню, просто добавив их в текстовый файл (или XML, или JSON, или любой формат, который вы хотите), но это еще одна тема.

ответил deepee1 14 J0000006Europe/Moscow 2013, 01:05:29
0

Все хорошие ответы. Я хотел бы добавить свои два цента к ответу @ deepee1. Если вы сохраните класс FoodItem, который он предоставляет (с помощью конструктора), вы можете создать список продуктов питания, а затем создать все остальное с полностью сухим кодом. Вы даже можете легко переместить определения из кода. Не говоря уже о создании n разных пользовательских интерфейсов с одной и той же «логикой».

Вот что я сделал бы: (Простите любые ошибки, долгое время с WinForms :))

private List<FoodItem> foods = new[] {
    new FoodItem("Taco", 1.0),
    new FoodItem("Burrito", 2.0),
    new FoodItem("Fajita", 1.5)
};
private const int buttonMargin = 5;

protected void Form_Load(...)
{
    CreateButtons();
}

private void CreateButtons()
{
    for(var i = 0; i<foods.Length; i++)
        AddButton(foods[i], i);
}

private void AddButton(FoodItem food, int index)
{
    var btn = new Button();
    btn.Id = "Button_" + i;
    btn.Tag = food;
    btn.Click += FoodClicked;
    btn.Top = btn.Height*index + buttonMargin*index;
    // Whatever initialization code you have
    Controls.Add(btn);
}

private void FoodClicked(object sender, EventArgs e)
{
    var button = (Button)sender;
    var food = (food)button.Tag;
    // Do whatever with the food..
}

Я просто перечитываю комментарии и понимаю, что вам нужен пейджинг. Добавьте личную внутреннюю страницу и приватную int-страницу, затем добавьте умножение на продукты [i] в ​​CreateButtons и замените foods.Length на страницу. У вас может быть такой массив, который вам нужен.

ответил Lars-Erik 21 J0000006Europe/Moscow 2013, 00:31:29

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132