澄清:目标是让我的 UIPList 1.能够观察任何 ObservableList,其中 T 是 iUIP 或其继承者之一,2.能够在列表,以及 3. 能够随时更改正在观看的列表(并且只能观看一个列表)。
我可以绘制 gui 按钮并让第一只 watch 正常工作(使用下面的 hacky 代码),但是无法将引用存储在 UIPList 中,因此当我想观看其他内容时我可以从该列表中取消订阅。我不能在不失去上面提到的第三种能力的情况下将它变成“UIPList”(这将使存储引用成为可能)。
我现在正在尝试让菜单(谁知道涉及什么 UIPLists 和 ObservableLists)在内容更改时处理取消订阅,但理想情况下我可以将 ObservableList 传递给 UIPList,它会知道如何观看它,绘制图形用户界面,并在它获得新列表时取消订阅。
原帖:
我有UIPList
应该看ObservableList<T> where T:iUIP
. ( iUIP
表示具有可以在 UIPList
中绘制的按钮的类)。
问题是我无法存储对列表的本地引用,因为它可能是 ObservableList<iUIP>
或者它可以是 ObservableList<Character>
或者 ObservableList<Organization>
等等(其他类继承 iUIP
)。
我不能使用 ObservableList<iUIP>
在 UIPList
作为引用,因为我可能想观看无法转换为 ObservableList<iUIP>
的列表尽管字符继承自 iUIP,因此无法存储对列表 UIPList
的本地引用应该观看。
我使用 SetWatchList<T>(ObservableList<T> list)
UIPList
上的方法拿一个列表来观看,但由于没有引用原始列表,当我想更改 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);
}
}
}
最佳答案
使整个类通用
public class UIPList<T> : MonoBehaviour where T : iUIP
然后您可以存储对列表的引用。这更好地封装了列表的实际内容。
不要忘记也从您的方法中删除通用约束
public void WatchList(ObservableList<T> list)
关于c# - 在不知道 T 的情况下保留 List<T> 的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21566253/