Метод add не работает в событии button_click, но работает в form_load C # - PullRequest
0 голосов
/ 19 февраля 2019

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

До сих пор я работал с несколькими функциями, и все работало нормально, пока я не попыталсядобавить новую машину на стоянке.

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

Мой класс такой:

class Parking
{
    public int Spot { get; set; }
    public string Plate { get; set; }
    public DateTime EnterTime { get; set; }
    public DateTime? ExitTime { get; set; }

    public Parking(int spot, string plate, DateTime enterTime)
    {
        Spot = spot;
        Plate = plate;
        EnterTime = enterTime;
        ExitTime = null;
    }
}

, и мой код пока:

public partial class Form1 : Form
{
    Timer clock = new Timer();

    List<Parking> parking = new List<Parking>();

    public Form1()
    {
        InitializeComponent();
        GetLoadDataBase();
    }

    private void GetLoadDataBase()
    {
        parking.AddRange(new List<Parking>
        {
            new Parking(1, "TKN1893", DateTime.Now),            
            new Parking(2, "TKN1951", DateTime.Now),
            new Parking(3, "TNA725", DateTime.Now),
            new Parking(4, "TNA725", DateTime.Now),
            new Parking(5, "TNA725", DateTime.Now),
            new Parking(6, "TNA725", DateTime.Now),
            new Parking(7, "TNA725", DateTime.Now),
            new Parking(8, "TNA725", DateTime.Now)
        });                     
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        clock.Interval = 1000;
        clock.Tick += new EventHandler(this.clock_Tick);
        clock.Start();

        *parking.Add(new Parking(10, "IP3147", DateTime.Now));

        dataGridView1.DataSource = parking;            
    }              

    private void DataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        try
        {
            string spot = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
            string plate = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
            string enterTime = dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString();
            ExitTimeInsert(e.RowIndex, parking);
            string exitTime = dataGridView1.Rows[e.RowIndex].Cells[3].Value.ToString();

            string BoxText = spot + " " + plate + " " + enterTime + " " + exitTime;

            DialogResult charge = MessageBox.Show(BoxText, "Test", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (charge == DialogResult.Yes)
            {
                parking[e.RowIndex] = null;
                dataGridView1.Refresh();
            }
            else
            {
                parking[e.RowIndex].ExitTime = null;                    
            }
        }
        catch(NullReferenceException)
        {
            MessageBox.Show("The Spot is Empty!");
        }

    }

    private void ExitTimeInsert(int index, List<Parking> parking)
    {
        parking[index].ExitTime = DateTime.Now;
    }

    private void clock_Tick(object sender, EventArgs e)
    {
        //get current time
        int hh = DateTime.Now.Hour;
        int mm = DateTime.Now.Minute;
        int ss = DateTime.Now.Second;

        //time
        string date = DateTime.Now.Date.ToLongDateString();
        string time = "";

        //padding leading zero
        if (hh < 10)
        {
            time += "0" + hh;
        }
        else
        {
            time += hh;
        }
        time += ":";

        if (mm < 10)
        {
            time += "0" + mm;
        }
        else
        {
            time += mm;
        }
        time += ":";

        if (ss < 10)
        {
            time += "0" + ss;
        }
        else
        {
            time += ss;
        }

        //update label
        label1.Text = time;
        label2.Text = date;
    }

    private void Exit_Click(object sender, EventArgs e)
    {
        System.Windows.Forms.Application.Exit();
    }

    private void Input_Button_Click(object sender, EventArgs e)
    {
        **Parking Adition = new Parking(10, "IP3147", DateTime.Now);
        **parking.Add(Adition);
        **parking.Add(new Parking(10, "IP3147", DateTime.Now));
        **Add_Record(textBox1.Text);
        **dataGridView1.DataSource = parking;
        dataGridView1.Refresh();
    }

    private void Add_Record(string value)
    {
        **parking.Add(new Parking(10, value, DateTime.Now));
        **dataGridView1.DataSource = parking;
    }
}

Надеюсь, это имеет смысл:

"*" "Реализации, которые работали"

"**" "Реализации пробовали отдельно не все вместе, которые не работали"

Все остальное работает отлично.

Спасибо всем за то, что вы так полезны

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Когда DataSource DataGridView является стандартным List<T>, изменения содержимого List<T> автоматически не отражаются в DataGridView: List<T> не будет отправлять уведомления об обновлении.
Повторная установка свойства DataSource дляDataGridView к тому же List<T> также не обновит данные, потому что ссылка на объект DataSource фактически одинакова.

Это можно увидеть в источнике .Net: DataGridView.DataSource свойство setter .

set
{
    if (value != this.DataSource) { ...  } 

value - от = до this.DataSource: источник данных тот же, поэтому никаких действий не выполняется.

Если для свойства DataSource установлено значение null, а затем для предыдущего значения List<T> произойдет сброс источника данных.

Другим вариантом, вероятно, предпочтительным, является использование BindingList вместо List<T>.

Класс BindingList<T> может использоваться в качестве базового класса для создания двустороннего механизма привязки данных.BindingList<T> предоставляет конкретную, обобщенную реализацию интерфейса IBindingList.

Давайте сделаем это, используя текущую настройку:

  1. Add Parking элементов в BindingList (конструктор форм или Form.Load)
  2. Установите свойство DataGridView.DataSource для объекта BindingList.

Использование BindingList - это почти то же самое, что и использование стандартного List<T>.
Обратите внимание, что при добавлении или удалении элемента из BindingList DataGridView обновляется немедленно безтребующие каких-либо дальнейших действий:

DataGridView BindingList

private BindingList<Parking> parking = null;

public Form1()
{
    InitializeComponent();

    var tmpList = new List<Parking>
    {
        new Parking(1, "TKN1893", DateTime.Now),
        new Parking(2, "TKN1951", DateTime.Now),
        new Parking(3, "TNA725", DateTime.Now),
    };
    this.parking = new BindingList<Parking>();
    tmpList.ForEach(elm => parking.Add(elm));
}

private void Form1_Load(object sender, EventArgs e)
{
    //(...)
    this.dataGridView1.DataSource = this.parking;            
}              

private void btnAddRecord_Click(object sender, EventArgs e)
{
    this.parking.Add(new Parking(10, "IP3147", DateTime.Now));
}

private void btnRemoveRecord(string value)
{
    this.parking.RemoveAt(0);
}
0 голосов
/ 19 февраля 2019

Вам нужно будет обернуть dataGridView1 UpdatePanel и добавить Input_Button как trigger.Убедитесь, что dataGridView1.Refresh() вызывается в методе Input_Button_Click.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...