Как я могу управлять динамически созданными элементами управления? - PullRequest
1 голос
/ 23 февраля 2012

Допустим, у меня есть форма, в которой кто-то может занести в каталог имена нескольких людей, их штат и город?

Предположим, у меня уже есть все государства / города в базе данных. (таблица для каждого штата с указанием городов в каждой таблице)

Поле имени будет TextBox. И поля State & City будут ComboBox (DropDownLists).

Одна строка (для записи одного человека) уже существует в форме. Но я хочу, чтобы пользователь мог динамически добавлять строки записей, нажимая кнопку «Добавить человека».

Следующий шаг - это то, где я борюсь. В каждой динамически добавляемой строке полей я хотел бы, чтобы второй ComboBox (Cities) заполнялся в зависимости от того, какое состояние выбрано в первом поле со списком. Кроме того, комбинированный список городов будет отключен до тех пор, пока не будет выбран комбинированный список состояний.

Мой код выглядит примерно так:

    public ComboBox cbState;
    public ComboBox cbCities;
    public static int NumberOfPeople = 1;


    private void btnAddNewPerson_Click(object sender, EventArgs e)
    {

        NumberOfPeople++;

        TextBox txtPerson = new TextBox();
        txtPerson.Name = "Person" + NumberOfPeople;
        Panel.Controls.Add(txtPerson);

        //  ADD State ComboBox
        cbState = new ComboBox();
        cbState.Name = "State" + NumberOfPeople;
        cbState.Enabled = true;
        cbState.DropDownStyle = ComboBoxStyle.DropDownList;
        Panel.Controls.Add(cbState);

        //  ADD City ComboBox
        cbCity = new ComboBox();
        cbCity.Name = "City" + NumberOfPeople;
        cbCity.DropDownStyle = ComboBoxStyle.DropDownList;
        cbCity.Enabled = false;
        cbCity.SelectedValueChanged += new System.EventHandler(this.ChangeState);
        Panel.Controls.Add(cbCity);

    }

    private void ChangeState(object sender, EventArgs e)
    {

       ..... Don't know how to properly identify the City ComboBox that is in the same row as the State ComboBox that was just changed, and manipulate/populate it.....

    }

Кто-нибудь может помочь мне решить эту проблему?

Буду очень признателен !!

Ответы [ 4 ]

0 голосов
/ 03 августа 2016

Прежде всего вы должны найти имя поля со списком, которым хотите манипулировать.

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

вот код для этого

    private void ChangeState(object sender,EventArgs e){
        ComboBox stateComboBox= (ComboBox)sender;
        //find the name of target City ComboBox
        string cityComboName = "City"+stateComboBox.Name.Substring(5); // 5 is the Length of 'State'
        ComboBox cityComboBox=null;
        foreach(Control cntrl in panel1.Controls){
            if (cntrl.Name == cityComboName) {
                cityComboBox= (ComboBox)cntrl;
                break;
            }
        }
        if (cityComboBox!= null) {
            cityComboBox.Enabled = true;
            // now you have the both cityComboBox and stateComboBox Of the same Row
        }
    }
0 голосов
/ 23 февраля 2012

Прежде всего, я бы создал дополнительный класс (например, с именем Row), который содержит все элементы управления одной строки.Таким образом, вы можете инкапсулировать элементы управления одного человека в один объект.
Ваш класс Form получает член списка таких объектов строки, как
List<Row> _rows = new List<Row>();.

В конструкторе этого класса Row Вы создаете элементы управления одной строки и назначаете обработчики событий для события SelectedValueChanged элементов управления Combobox.

0 голосов
/ 23 февраля 2012

Вы можете использовать Control.Tag, чтобы прикрепить объект данных к вашим элементам управления.Посмотрите, как элементы управления представлены друг другу в примере.

private void btnAddNewPerson_Click( object sender, EventArgs e )
{
    AddPersonRow();
}

private void AddPersonRow()
{
    // Create combo boxes
    ComboBox cbCity = new ComboBox();
    ComboBox cbState = new ComboBox();

    // Introduce them to each other
    cbCity.Tag = cbState;
    cbState.Tag = cbCity;

    //  ADD State ComboBox
    cbState.Name = "State" + NumberOfPeople;
    cbState.Enabled = true;
    cbState.DropDownStyle = ComboBoxStyle.DropDownList;
    cbState.SelectedValueChanged += new EventHandler( cbState_SelectedValueChanged );
    panel.Controls.Add( cbState );

    // Populate the states sombo
    PopulateStateCombo( cbState );

    //  ADD City ComboBox
    cbCity.Name = "City" + NumberOfPeople;
    cbCity.DropDownStyle = ComboBoxStyle.DropDownList;
    cbCity.Enabled = false;
    cbCity.SelectedValueChanged += new EventHandler(cbCity_SelectedValueChanged);
    panel.Controls.Add( cbCity );
}

void cbState_SelectedValueChanged( object sender, EventArgs e )
{
    ComboBox cbState = sender as ComboBox;
    ComboBox cbCity = cbState.Tag as ComboBox;

    cbCity.Enabled = true;

    // .. Go ahead and populate cbCity by cbState's selected value ..
}

void cbCity_SelectedValueChanged( object sender, EventArgs e )
{
    // Up to you...
}

Обратите внимание, что вместо рукопожатия ComboBox вы можете создать класс, который будет содержать оба ComboBox, ваш элемент управления TextBox, строкучисло и т. д., а затем установите тег всех этих элементов управления на сам класс.

public class PersonRow
{
    public int RowNum { get; private set; }
    public TextBox NameTextBox { get; private set; }
    public ComboBox CityCombo { get; private set; }
    public ComboBox StateCombo { get; private set; }

    public PersonRow( int rowNum )
    {
        RowNum = rowNum;

        // Create the controls
        NameTextBox = new TextBox();
        CityCombo = new ComboBox();
        StateCombo = new ComboBox();

        // Bind them to this instance
        NameTextBox.Tag = this;
        CityCombo.Tag = this;
        StateCombo.Tag = this;

        //.. continue as in the prev. example..
    }
}
0 голосов
/ 23 февраля 2012

Вы можете использовать словарь

Dictionary<ComboBox,ComboBox> CityToStateMap = new Dictionary<ComboBox,ComboBox>();

тогда при добавлении строки

CityToStateMap[cbState] = cbCity;

тогда при изменении состояния

ComboBox city = CityToStateMap[(ComboBox)sender];
...