Reputation: 541
I need to disable 1(or 2) dropdown option from a dropdown menu in Unity.
The dropdown menu should not be repopulated.
There should not be any deletion/deactivated options from the dropdown menu
Anyone have any idea how to do this. ?
Upvotes: 5
Views: 9760
Reputation: 90630
Similar to this answer but a slightly different approach.
The other answer uses a hardcoded toggle.name == "Item 1: Option B"
to compare the buttons. I'd rather use a central and index-based system:
Put this component on the DropDown
[RequireComponent(typeof(Dropdown))]
[DisallowMultipleComponent]
public class DropDownController : MonoBehaviour, IPointerClickHandler
{
[Tooltip("Indexes that should be ignored. Indexes are 0 based.")]
public List<int> indexesToDisable = new List<int>();
private Dropdown _dropdown;
private void Awake()
{
_dropdown = GetComponent<Dropdown>();
}
public void OnPointerClick(PointerEventData eventData)
{
var dropDownList = GetComponentInChildren<Canvas>();
if (!dropDownList) return;
// If the dropdown was opened find the options toggles
var toogles = dropDownList.GetComponentsInChildren<Toggle>(true);
// the first item will always be a template item from the dropdown we have to ignore
// so we start at one and all options indexes have to be 1 based
for (var i = 1; i < toogles.Length; i++)
{
// disable buttons if their 0-based index is in indexesToDisable
// the first item will always be a template item from the dropdown
// so in order to still have 0 based indexes for the options here we use i-1
toogles[i].interactable = !indexesToDisable.Contains(i - 1);
}
}
// Anytime change a value by index
public void EnableOption(int index, bool enable)
{
if (index < 1 || index > _dropdown.options.Count)
{
Debug.LogWarning("Index out of range -> ignored!", this);
return;
}
if (enable)
{
// remove index from disabled list
if (indexesToDisable.Contains(index)) indexesToDisable.Remove(index);
}
else
{
// add index to disabled list
if (!indexesToDisable.Contains(index)) indexesToDisable.Add(index);
}
var dropDownList = GetComponentInChildren<Canvas>();
// If this returns null than the Dropdown was closed
if (!dropDownList) return;
// If the dropdown was opened find the options toggles
var toogles = dropDownList.GetComponentsInChildren<Toggle>(true);
toogles[index].interactable = enable;
}
// Anytime change a value by string label
public void EnableOption(string label, bool enable)
{
var index = _dropdown.options.FindIndex(o => string.Equals(o.text, label));
// We need a 1-based index
EnableOption(index + 1, enable);
}
}
Configure in the Inspector
or via scripts e.g.
dropDownReference.GetComponent<DropDownController>().EnableOption("Option B", false);
Upvotes: 11
Reputation: 1889
You can achieve this using the Toggle
component from DropDown->Template->ViewPort->Content->Item.
This script is creating items every time DropDown
menu is selected. You can just access Toogle
and disable interactable field like this:
void Start ()
{
//This script should be attached to Item
Toggle toggle = gameObject.GetComponent<Toggle>();
Debug.Log(toggle);
if (toggle != null && toggle.name == "Item 1: Option B")
{
toggle.interactable = false;
}
}
You can also see a DropDown list is created every time arrow on DrowDown is clicked and destroyed when menu is closed.
Upvotes: 3