Я пытаюсь придумать способ фильтрации списка кнопок, которые я динамически создаю, на основе значений, зацикленных в базе данных SQlite.Каждая кнопка помечена именем студента, и может быть большое количество кнопок, следовательно, необходимо отфильтровать кнопки.
Я создаю свои кнопки так:
public RectTransform GridWithNameElements;
public GameObject StudentNamePrefabButton;
while (reader.Read())
{
//create a new button object and use the prefab button to make sure spacing etc is correct
goButton = (GameObject)Instantiate(StudentNamePrefabButton);
//set the parent of the button
goButton.transform.SetParent(GridWithNameElements, false);
goButton.transform.localScale = new Vector3(1, 1, 1);
//set the text of the button. Array value is 0 as the student name is always at position 0 on each iteration
goButton.GetComponentsInChildren<Text>()[0].text = reader["fullName"].ToString()+" | "+ reader["studentNumber"].ToString();
goButton.name = reader["studentID"].ToString();
Button tempButton = goButton.GetComponent<Button>();
int tempInt = i;
tempButton.onClick.AddListener(() => ButtonClicked(tempInt));
i++;
Debug.Log(goButton.name);
}
Затем ясоздал поле ввода и прикрепил скрипт к onValueChanged
в поле ввода и попытался написать скрипт.
//This method is called when the student attempts to search for their own name when taking the individual quiz
public void SearchExistingStudentName()
{
//Get the name entered from the text field
string student_name = searchExistingStudentNameInput.text;
//Add names that exist to the new list
List<string> names = new List<string>();
names.Clear();
//sets an id to the onclick listener of newly created buttons
int x = 0;
//if a new button object exists and the name was entered and then removed, clear it from the list and remove the created button
if (student_name == "")
{
//Clear the filtered names List
names.Clear();
x = 0;
//Destroy the create filter buttons if the user clears the text area
GameObject[] objects = GameObject.FindGameObjectsWithTag("filterButton");
//loop through the buttons that share the tag "filterButton"
for (int count = 0; count < objects.Length; count++)
{
Destroy(objects[count]);
Debug.Log("Number of objects to be deleted " + objects.Length);
}
//Loop through and show all children
foreach (Transform child in GridWithNameElements)
{
child.gameObject.SetActive(true);
}
}
else if (student_name != "")
{
int count = 0;
int filteredNameCount = 0;
int filteredIDCount = 1;
//loop through the list of buttons with student names
for (int i = 0; i < GridWithNameElements.childCount; i++)
{
Debug.Log("Children of grid "+GridWithNameElements.childCount);
//Check if the user has typed their name with capitals or lowercase etc, and check the inputted value against names already in the list
//If true, proceed
if (GridWithNameElements
.GetComponentsInChildren<Text>()[i].text.Contains(student_name) || GridWithNameElements
.GetComponentsInChildren<Text>()[i].text.ToLower().Contains(student_name) || GridWithNameElements
.GetComponentsInChildren<Text>()[i].text.ToUpper().Contains(student_name))
{
//If the name entered contains letters found in the parent GridWithNameElements, then add them to the list array and their name value (unique id)
names.Add(GridWithNameElements.GetComponentsInChildren<Text>()[i].text.Replace(@"[", string.Empty).Replace(@"]", string.Empty));
names.Add(GridWithNameElements.GetChild(i).name); //this is the unique id of the student
Debug.Log("Number of items in filtered names list " + names.Count);
//Loop through and hide all children and hide them
if (count == 0)
{
foreach (Transform child in GridWithNameElements)
{
child.gameObject.SetActive(false);
}
}
count++;
//Then create a button that represents a name added to the names List
newButton = (GameObject)Instantiate(StudentNamePrefabButton);
//set the parent of the button
newButton.transform.SetParent(GridWithNameElements, false);
newButton.transform.localScale = new Vector3(1, 1, 1);
//set the text of the button. Array value is 0 as the student name is always at position 0 on each iteration
newButton.GetComponentsInChildren<Text>()[filteredNameCount].text = names[filteredNameCount].ToString();
newButton.name = names[filteredIDCount].ToString().Trim();
newButton.tag = "filterButton";
filteredNameCount++;
filteredIDCount++;
//Then add a click listener to the button
Button tempButton = newButton.GetComponent<Button>();
int tempInt = x;
tempButton.onClick.AddListener(() => ButtonClicked(tempInt));
x++;
// Debug.Log("Student Unique ID " + newButton.name);
}
}
count = 0;
}
}
Я надеялся просто перебрать все элементы списка и скрыть те, которые нене соответствует поисковому запросу.Однако в настоящий момент мой цикл неверен, так как я получаю исключение за пределами границ (что, я думаю, связано с динамическим добавлением нового дочернего элемента при выполнении поиска).Я вижу это в журнале консоли, однако, программа выполняется должным образом (так что это проблема, но на данный момент не самая большая).
Я скрываю исходный список и показываю новый список на основе критериев соответствия.
Однако я всегда возвращаю только одно возможное имя, а не кучу возможных вариантов.Например, если бы у меня были имена Бен Джонс и Боб Дилан, основываясь на моем коде на данный момент, я только смогу вернуть Бена Джонса, а не Боба Дилана.
Я чувствую, что поступаю неправильноЯ хочу что-то похожее на this и не могу его воссоздать.Однако я пытаюсь выяснить, движусь ли я в правильном направлении или нет.
ОБНОВЛЕНИЕ
Я думаю, что нашел причину IndexOutOfRangeException: Array index is out of range.
Это потому, что всякий раз, когда явведите букву, она вызывает метод SearchExistingStudentName()
.Это означает, что если введенная буква находится в одном из имен, она добавляется в список - только буква.Вот почему я могу вернуть только одно имя, а не список возможных имен.Поэтому я думаю, что оператор if нуждается в изменении, которое я сейчас пытаюсь рассмотреть.
Мне удалось сузить исключение массива в коде до следующего раздела:
//Loop through and hide all children and hide them
if (count == 0)
{
foreach (Transform child in GridWithNameElements)
{
child.gameObject.SetActive(false);
}
}
count++;
//Then create a button that represents a name added to the names List
newButton = (GameObject)Instantiate(StudentNamePrefabButton);
//set the parent of the button
newButton.transform.SetParent(GridWithNameElements, false);
newButton.transform.localScale = new Vector3(1, 1, 1);
//set the text of the button. Array value is 0 as the student name is always at position 0 on each iteration
newButton.GetComponentsInChildren<Text>()[filteredNameCount].text = names[filteredNameCount].ToString();
newButton.name = names[filteredIDCount].ToString().Trim();
newButton.tag = "filterButton";
filteredNameCount++;
filteredIDCount++;