c# - 使用下拉菜单索引删除列表成员正在删除保存数据中的整个列表
问题描述
我正在尝试为在 Unity 中制作的 android 应用程序执行用户名保存数据的粗略实现。这个应用程序不会被部署,我不需要担心用户名的密码,所以我只是使用持久数据路径来保存一个文本文件。
输入的用户名被添加到字符串列表中,然后用于填充我的 UI 中的下拉菜单。
我能够很好地创建文本文件,并保存到它,然后从中加载。但是,我正在尝试实现一个删除功能,允许用户删除他们不再希望使用的用户名,这应该从字符串列表中删除用户名,从下拉菜单中删除它,以及调用“保存" 将新列表重新保存到同一文本文件的函数。
目前,我让用户从下拉列表中选择有问题的用户名,然后按“删除”按钮,该按钮应使用下拉菜单的索引并使用“RemoveAt”功能删除字符串列表中的相应成员。
但是,这似乎删除了整个列表,并且在打开保存文本文件时,它现在是空的。我认为我删除列表成员的方式有问题,或者应用程序重新保存新列表的方式有问题。
public class SignInManager : MonoBehaviour {
List<string> menuOptions = new List<string>();
//USER INPUT
public InputField newUserName;
public Dropdown selectedUsername;
public string userName;
public int dropDownOption;
//SAVING
FileInfo f;
// Use this for initialization
void Start () {
f = new FileInfo(Application.persistentDataPath + "save.txt");
//Load existing username options here
if (f.Exists)
{
Load();
}
Save();
Load();
}
//When the sign-in button is clicked
public void OnClick()
{
if (newUserName.text != "" ^ selectedUsername.value != 0)
{
//Save entered user data, later export to desired location
if (newUserName.text != "")
{
userName = newUserName.text;
selectedUsername.AddOptions(new List<string> { userName }); //AddOptions must take a list as parameter, but this is just a list of one each time
menuOptions.Add(userName);
Save();
Load();
//Save data to text file here
//Set current username to entered one
}
else if(selectedUsername.value != 0)
{
dropDownOption = selectedUsername.value; //Set current username to selected one
}
}
//When the user signs out
public void OnReturnClick()
{
newUserName.text = "";
selectedUsername.value = 0;
userName = "";
dropDownOption = 0;
}
}
public void DeleteOption()
{
if (selectedUsername.value != 0)
{
Debug.Log("Removing: " + selectedUsername.value);
//menuOptions.RemoveAt(selectedUsername.value);
selectedUsername.options.RemoveAt(selectedUsername.value);
selectedUsername.value = 0;
Save();
Load();
}
}
void Save()
{
StreamWriter w;
if (!f.Exists)
{
w = f.CreateText();
for (int i = 0; i < menuOptions.Count; i++)
{
w.WriteLine(menuOptions[i]);
}
}
else
{
f.Delete();
w = f.CreateText();
for (int i = 0; i < menuOptions.Count; i++)
{
w.WriteLine(menuOptions[i]);
}
}
w.Flush();
w.Close();
}
void Load()
{
if (f.Exists && selectedUsername != null) //don't know why selectedUsername sometimes comes up as null, but that additional condition was needed
{
selectedUsername.ClearOptions();
selectedUsername.AddOptions(new List<string> { "" });
StreamReader r = File.OpenText(Application.persistentDataPath + "save.txt");
string line;
while ((line = r.ReadLine()) != null)
{
menuOptions.Add(line);
selectedUsername.AddOptions(new List<string> { line });
}
r.Close();
}
}
}
}
解决方案
所以我自己尝试了这个。首先,我看不出你是如何让整个列表消失的。当我在 Unity 中进行测试时,这并没有发生在我身上。也许当您的文件消失时,您正在路径中检查它C:\Users\Andy\AppData\LocalLow\{companyName}\{projectName}\save.txt
如果您这样做,并且由于某种原因在该位置有一个文件,那么该文件应该是空的。您将文件列为Application.persistantDataPath + "save.txt"
并且 Application.persistantDataPath 不返回结尾。因此,无论这是否按您认为的方式工作,最好是您的文件路径Application.persistantDataPath + @"\save.txt"
其次,虽然我没有看到整个列表消失,但列表和文件不会更新。这是因为你在做
//menuOptions.RemoveAt(selectedUsername.value);
selectedUsername.options.RemoveAt(selectedUsername.value);
selectedUsername.value = 0;
虽然您的保存功能确实w.WriteLine(menuOptions[i]);
您正在更改选项,然后尝试从错误的列表中保存。解决这个问题的简单方法就是看起来你第一次做对了,取消注释//menuOptions.RemoveAt(selectedUsername.value);
并删除selectedUsername.options.RemoveAt(selectedUsername.value);
毕竟,你的负载应该对你的下拉菜单进行更改。
您的负载也直接添加到列表中,因此每次调用时,您的列表都会变得越来越长。您的负载应该在添加到列表之前清除列表。
另外,我注意到在您的保存方法中,您将名称直接添加到保存列表和下拉列表中。这是您在下拉列表中看到更改的唯一原因,因为加载未运行,因为您的 f 变量仍然认为该文件不存在。而且您的文件更改都是附加的,因此即使文件正常工作,文件也会发生奇怪的事情。我建议您使用我所做的这些更改:
void Start()
{
f = new FileInfo(Application.persistentDataPath + @"\save.txt");
//Load existing username options here
if (f.Exists)
{
Load();
}
Save();
Load();
}
void Save()
{
StreamWriter w = new StreamWriter(Application.persistentDataPath + @"\save.txt", false);
for (int i = 0; i < menuOptions.Count; i++)
{
w.WriteLine(menuOptions[i]);
}
w.Close();
}
void Load()
{
f = new FileInfo(Application.persistentDataPath + @"\save.txt");
if (f.Exists && selectedUsername != null) //don't know why selectedUsername sometimes comes up as null, but that additional condition was needed
{
selectedUsername.ClearOptions();
selectedUsername.AddOptions(new List<string> { "" });
StreamReader r = new StreamReader(Application.persistentDataPath + @"\save.txt");
string line;
menuOptions.Clear();
while ((line = r.ReadLine()) != null)
{
menuOptions.Add(line);
selectedUsername.AddOptions(new List<string> { line });
}
selectedUsername.RefreshShownValue();
r.Close();
}
}
推荐阅读
- ruby-on-rails - form_tag 远程 true 不作为 json 请求处理 rails 5
- module - 在 Rust 2018 中使用模块时,如何解决错误“根目录中没有模块”?
- javascript - 未定义 chrome.storage.sync.get?
- python - 更新 numpy 数组中的值而无需繁琐的 for 循环
- node.js - 根据 Modernizr 服务不同的资产
- python - 如何使用 docker 容器运行服务器?
- python - 使用列表设计可扩展的命令行界面
- flutter - 有没有办法在颤振中打开其他应用程序
- typescript - 打字稿:检查类型是否为联合
- tizen-studio - 签署 Tizen 包时密码无效