Вопрос или проблема
У меня есть 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
, улучшая пользовательский опыт.