Сохранение состояния выбранных элементов CheckedListBox при поиске [дубликат]

Вопрос или проблема

У меня есть CheckedListBox в UserControl.
Во время поиска элементов отмеченные флажки снимаются. Я много раз пытался решить эту проблему, но возникает исключение.

Сначала поиск работает нормально. Проблема заключается в состоянии проверки.

private DataTable GetDataTable()
{
    var dt = new DataTable();

    using (var CON = new SqlConnection("Строка подключения"))
    using (var cmd = new SqlCommand("Select Property_Name, Property_Id from property", CON))
    using (var da = new SqlDataAdapter(cmd))
    {
        CON.Open();
        da.Fill(dt);
    }

    return dt;
}
private void Searchtext_TextChanged(object sender, EventArgs e)
{  
        if (checkedListBox1.DataSource is DataTable dt)
        {
            var str = Searchtext.Text.Trim();

            dt.DefaultView.RowFilter = string.IsNullOrEmpty(str)
            ? null
            : $"Property_Name LIKE '%{str}%'";
        
        }
}
private void LoadProperty()
{
    checkedListBox1.DisplayMember = "Property_Name";
    checkedListBox1.ValueMember = "Property_Id";
    checkedListBox1.DataSource = GetDataTable();
}

Я размещал код для ввода поиска.

Проблема, вероятно, возникает из-за того, что каждый раз, когда вы фильтруете данные в CheckedListBox, он перезагружает DataSource, что вызывает сброс состояния проверки.

Я думаю, что вы можете исправить это, сохранив состояния проверки элементов перед применением фильтра и восстановив их после, вот так:

// сохранить состояния перед фильтрацией
private Dictionary<int, bool> GetCheckedStates()
{
    var checkedStates = new Dictionary<int, bool>();

    for (int i = 0; i < checkedListBox1.Items.Count; i++)
    {
        var row = (DataRowView)checkedListBox1.Items[i];
        int propertyId = (int)row["Property_Id"];
        checkedStates[propertyId] = checkedListBox1.GetItemChecked(i);
    }

    return checkedStates;
}

// затем восстановить состояния проверки
private void RestoreCheckedStates(Dictionary<int, bool> checkedStates)
{
    for (int i = 0; i < checkedListBox1.Items.Count; i++)
    {
        var row = (DataRowView)checkedListBox1.Items[i];
        int propertyId = (int)row["Property_Id"];

        if (checkedStates.ContainsKey(propertyId))
        {
            checkedListBox1.SetItemChecked(i, checkedStates[propertyId]);
        }
    }
}

private void Searchtext_TextChanged(object sender, EventArgs e)
{
    if (checkedListBox1.DataSource is DataTable dt)
    {
        // Сохранить текущие состояния проверки
        var checkedStates = GetCheckedStates();

        var str = Searchtext.Text.Trim();
        dt.DefaultView.RowFilter = string.IsNullOrEmpty(str)
            ? null
            : $"Property_Name LIKE '%{str}%'";

        RestoreCheckedStates(checkedStates);
    }
}

private void LoadProperty()
{
    checkedListBox1.DisplayMember = "Property_Name";
    checkedListBox1.ValueMember = "Property_Id";
    checkedListBox1.DataSource = GetDataTable();
}

Суть в том, что перед применением фильтров вы сохраняете состояния проверки ваших элементов в словаре. После фильтрации данных состояния проверки восстанавливаются благодаря словарю. Теперь CheckedListBox сохраняет отмеченные элементы, даже когда применяется фильтр.

Ответ или решение

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

Шаг 1: Сохранение состояния чекбоксов

Создайте метод, который будет сохранять состояния чекбоксов в словаре, где ключом будет идентификатор свойства, а значением – состояние (проверен или нет):

private Dictionary<int, bool> GetCheckedStates()
{
    var checkedStates = new Dictionary<int, bool>();

    for (int i = 0; i < checkedListBox1.Items.Count; i++)
    {
        var row = (DataRowView)checkedListBox1.Items[i];
        int propertyId = (int)row["Property_Id"];
        checkedStates[propertyId] = checkedListBox1.GetItemChecked(i);
    }

    return checkedStates;
}

Шаг 2: Восстановление состояния чекбоксов

Создайте метод для восстановления состояний чекбоксов из словаря:

private void RestoreCheckedStates(Dictionary<int, bool> checkedStates)
{
    for (int i = 0; i < checkedListBox1.Items.Count; i++)
    {
        var row = (DataRowView)checkedListBox1.Items[i];
        int propertyId = (int)row["Property_Id"];

        if (checkedStates.ContainsKey(propertyId))
        {
            checkedListBox1.SetItemChecked(i, checkedStates[propertyId]);
        }
    }
}

Шаг 3: Изменение обработчика событий текста

Теперь измените метод обработчика TextChanged, чтобы он сохранял и восстанавливал состояния чекбоксов:

private void Searchtext_TextChanged(object sender, EventArgs e)
{
    if (checkedListBox1.DataSource is DataTable dt)
    {
        // Сохранение текущих состояний чекбоксов
        var checkedStates = GetCheckedStates();

        var str = Searchtext.Text.Trim();
        dt.DefaultView.RowFilter = string.IsNullOrEmpty(str)
            ? null
            : $"Property_Name LIKE '%{str}%'";

        // Восстановление состояний чекбоксов
        RestoreCheckedStates(checkedStates);
    }
}

Шаг 4: Загрузка данных

Убедитесь, что метод загрузки данных корректно устанавливает DataSource для CheckedListBox:

private void LoadProperty()
{
    checkedListBox1.DisplayMember = "Property_Name";
    checkedListBox1.ValueMember = "Property_Id";
    checkedListBox1.DataSource = GetDataTable();
}

Заключение

Теперь, когда вы будете изменять текст в поле поиска, состояния чекбоксов будут сохраняться перед применением фильтра и восстанавливаться после него. Это позволит вам сохранить выбор при взаимодействии с CheckedListBox, улучшая пользовательский опыт.

Оцените материал
Добавить комментарий

Капча загружается...