澄清: 目标是使我的
UIPList
能够观察任何T为iUIP或其子类的ObservableList
,并且UIPrefab
按钮连接到列表中的,同时还能随时更改它正在观察的列表(并且仅观察一个列表)。
我可以画出GUI按钮并使用下面的hacky代码使其第一次观察成功,但没有办法将引用存储在UIPList
中,以便我可以在想要观看其他内容时取消订阅。如果将其转换为“UIPList”(这将使存储引用成为可能),则会失去上述第三个功能。
现在我正在尝试由菜单(了解所涉及的UIPLists
和ObservableLists
)负责在内容更改时取消订阅,但理想情况下,我只需将ObservableList
传递给UIPList
,它就能知道如何监视它、绘制GUI并在自己获得新列表时取消订阅。
UIPList
,它应该观察一个ObservableList<T> where T:iUIP
。(iUIP
指一个具有可以在UIPList
中绘制按钮的类)。
问题是我不能存储对列表的本地引用,因为它可以是ObservableList<iUIP>
或者ObservableList<Character>
或ObservableList<Organization>
等(其他继承类)。
我不能使用ObservableList<iUIP>
作为对UIPList
的引用,因为我可能想要观察一个无法强制转换为ObservableList<iUIP>
的列表,尽管角色是从继承而来的,因此没有办法存储对UIPList
应该观察的列表的本地引用。
我在UIPList
上使用了一个SetWatchList<T>(ObservableList<T> list)
方法来接收待观察的列表,但由于没有对原始列表的引用,当我想要更改UIPList
正在看的内容时,我就没有所需的引用来取消订阅以前的列表。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//using System.Collections.ObjectModel;
public class UIPList : MonoBehaviour
{
public GUIManager GUIManager;
public UILabel Title;
public UITable Contents;
// ObservableList<T>.ListChangedEventHandler subscribedChangeEvent;
public void WatchList<T>(ObservableList<T> list) where T: iUIP
{
this.subscribedChangeEvent = list.ListChanged;
list.ListChanged += DrawUIPList;//TODO make always clear prev?
DrawUIPList<T>(list);
}
//dont have a reference to the old list to know what to stop watching!
// public void StopWatchList<T>(ObservableList<T> list) where T: iUIP
// {
// list.ListChanged -= DrawUIPList;
// }
// Use this for initialization
protected void Start()
{
this.GUIManager = GUIManager.Find;
}
// Update is called once per frame
void Update()
{
}
void DrawUIPList<T>(object source, ObservableList<T>.ListChangedEventArgs e) where T : iUIP
{
DrawUIPList<T>(e.list);
}
void DrawUIPList<T>(ObservableList<T> list) where T:iUIP
{
//todo AddComponentMenu/RemoveItem/adjut ReadOnlyCollectionBase changed UIPs
ClearContents();
this.Contents.Reposition();
foreach (T uip in list)//TODO make this automatic, not need each one
{
// Debug.Log("Adding UIP:" + child.name);
if (uip.UIPButton is UIPCorporationButton)
UIPCorporationButton.Create(this.Contents.gameObject, (uip as Corporation));
if (uip.UIPButton is UIPCompanyButton)
UIPCompanyButton.Create(this.Contents.gameObject, (uip as Company));
if (uip.UIPButton is UIPAssetButton)
UIPAssetButton.Create(this.Contents.gameObject, (uip as Asset));
if (uip.UIPButton is UIPIndButton)
UIPIndButton.Create(this.Contents.gameObject, (uip as Industry));
if (uip.UIPButton is UIPSecButton)
UIPSecButton.Create(this.Contents.gameObject, (uip as Sector));
if (uip.UIPButton is UIPOperativeButton)
UIPOperativeButton.Create(this.Contents.gameObject, (uip as Operative));
if (uip.UIPButton is UIPAgencyButton)
UIPAgencyButton.Create(this.Contents.gameObject, (uip as Agency));
if (uip.UIPButton is UIPBrokerButton)
UIPBrokerButton.Create(this.Contents.gameObject, (uip as Broker));
if (uip.UIPButton is UIPCellButton)
UIPCellButton.Create(this.Contents.gameObject, (uip as Cell));
if (uip.UIPButton is UIPMissionButton)
UIPMissionButton.Create(this.Contents.gameObject, (uip as Mission));
if (uip.UIPButton is UIPObjectiveButton)
UIPObjectiveButton.Create(this.Contents.gameObject, (uip as Objective));
if (uip.UIPButton is UIPChallengeButton)
UIPChallengeButton.Create(this.Contents.gameObject, (uip as Challenge));
}
//this.Contents.Reposition();
this.Contents.repositionNow = true;
}
public void ClearContents()
{
// this.Contents.children.children.Clear();
int count = this.Contents.transform.childCount;
for (int i = count - 1; i >= 0; i--)
{
GameObject.Destroy(this.Contents.transform.GetChild(i).gameObject);
}
}
}