TestStack.White ListBox.SelectedItemText не работает
У меня есть WinForms
Диалог с 2 ListBox
управления. В тестируемом приложении двойной щелчок по любому элементу в одном из элементов управления списком (я назову это списком управления) приводит к выбору соответствующего элемента в другом списке (SLAVE LISTBOX).
Мой тест приводит к тому, что в СПИСОК УПРАВЛЕНИЯ будет сделано несколько записей. Затем тест выполняет ListBox.SelectedItem.DoubleClick()
на каждом из элементов списка управления, сравнивая ListBox.SelectedItemText
из обоих элементов управления списка.
В интерфейсе приложения это ВСЕГДА работает, но проверка вызова ListBox.SelectedItemText
для SLAVE LISTBOX возвращает текст, соответствующий тому, что правильно спит в пользовательском интерфейсе ТОЛЬКО на начальной итерации двойного клика \ сравнения.
Кто-нибудь может помочь мне понять, что я делаю неправильно? Спасибо!
Вот мой код:
public bool SelectMainEventViaErrorEvent(int eventIdx)
{
bool bSuccess = false;
errorEvents.Items.Select(eventIdx);
System.Threading.Thread.Sleep(1000);
errorEvents.Items.SelectedItem.DoubleClick();
System.Threading.Thread.Sleep(1000);
if (eventIdx > 0)
{
IVScrollBar vertScroll = mainEvents.ScrollBars.Vertical;
vertScroll.ScrollDownLarge();
}
if (errorEvents.SelectedItemText == mainEvents.SelectedItemText)
{
bSuccess = true;
}
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected error event = {errorEvents.SelectedItemText}");
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected main event = {mainEvents.SelectedItemText}");
return bSuccess;
}
Как видно из рисунка ниже, текст в обоих списках одинаков. Тем не менее, призыв к ListBox.SelectedItemText
для верхнего списка (SLAVE LISTBOX) возвращает значение из первой итерации, которая соответствует первому элементу в нижнем списке (CONTROL LISTBOX) во время первой итерации двойного щелчка / сравнения.
Доказательство того, что текст выбранных элементов списка совпадает
2 ответа
Сравнение с обычным текстом - плохая идея, так как "Текст"!= "Текст". Что вы могли бы использовать в вашем случае DisplayMember
а также ValueMember
свойства.
Я продемонстрирую это для вас с помощью ручного заполнения списков, но вы делаете это из базы данных или как вы это делаете.
Прежде всего создать class
это будет хранить ваши значения и его идентификаторы. Я обычно создаю это так (поэтому я могу использовать этот класс позже для чего-то другого)
public class Int_String
{
public int _int { get; set; } // Important to be declared like properties and not like variables
public string _string { get; set; }
}
Теперь давайте заполним наш список следующим образом:
public YourForm()
{
List<Int_String> list = new List<Int_String>();
list.Add(new Int_String { _int = 1, _string = "Some text" }); // I am populating it manually but you will populate it from DB or somewhere else
list.Add(new Int_String { _int = 2, _string = "Some other text" });
list.Add(new Int_String { _int = 3, _string = "One more text" });
// Now when we have list we need to bind it to our listbox.
// IMPORTANT!!!!!
// Display member and Value member properties SHOULD be able to be added before and after assigning datasource to control (like combobox) BUT for some reason on listbox it only works when you assign it AFTER you bind your datasource to listbox.
// If you ever work with other controls and use these values, ALWAYS declare display member and value member BEFORE you bind datasource. Why? For now let's just say it is much faster but explanation is for other question
myListBox1.DataSource = list;
myListBox1.DisplayMember = "_string"; // When you start typing .DisplayMember, you will not get that property in recommendation since it is hidden so do not think there is not that property there.
myListBox1.ValueMember = "_int"; // Same as above
}
Теперь, когда вы заполняете список, как этот, и второй, таким же образом с теми же идентификаторами, вы можете просто сделать if(listbox1.SelectedValue == listbox2.SelectedValue)
и сравнивать их, даже если их текст не равен, но идентификатор равен.
БОНУС: Также вы можете расширить класс следующим образом:
public class Int_String
{
public int _int { get; set; }
public string _string { get; set; }
public string SomethingOther = "AsD";
public bool IsTrue()
{
return true;
}
}
затем связать его таким же образом и сделать это:
Int_String item = listbox1.SelectedItem as Int_String;
bool check = item.IsTrue();
MessageBox.Show(item.SomethingOther);
Таким образом, в основном вы связываете целый класс для каждого элемента в списке, отображая пользователю одну из переменных (в нашем случае _string
), задавать ValueMember
к другой уникальной переменной, так что легко найти весь список и при необходимости получить весь класс из этого элемента.
Я никогда не мог заставить это работать, перебирая вперед errorEvent
listbox в моем автоматизированном тестовом коде, но он РАБОТАЕТ при повторении в обратном направлении errorEvent
ListBox.
Телефонный код:
for (int i = eventViewer.GetErrorEventsCount() - 1; i >= 0; i--)
{
bResult = eventViewer.SelectMainEventViaErrorEvent(i);
if (!bResult)
{
break;
}
System.Threading.Thread.Sleep(2000);
}
Код подтверждения:
public bool SelectMainEventViaErrorEvent(int eventIdx)
{
bool bSuccess = false;
DisableToolTips(true);
errorEvents.Select(eventIdx);
errorEvents.SelectedItem.DoubleClick();
System.Threading.Thread.Sleep(1000);
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected error event = {errorEvents.SelectedItemText}");
log.Info($"SelectMainEventViaErrorEvent({eventIdx}) selected main event = {mainEvents.SelectedItemText}");
if (errorEvents.SelectedItemText == mainEvents.SelectedItemText)
{
bSuccess = true;
}
return bSuccess;
}