[嗨,我是一名新程序员,在另一个问题的帮助下,我得到了一个男人的帮助。通过这种方法关闭并重新打开应用程序时,我设法保留了TextBox
数据:
public Form1()
{
InitializeComponent();
InitializeSavedValues();
textBox1.TextChanged += textBox1_TextChanged;
}
private void InitializeSavedValues()
{
textBox1.Text = (string)Properties.Settings.Default["TextBoxValue"];
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
Properties.Settings.Default["TextBoxValue"] = ((TextBox)sender).Text;
Properties.Settings.Default.Save();
}
现在,我想知道是否可以使用这种方法来保存TextBox
数据,但是使用制表符。说,我在winforms中使用TabControl
工具来添加/删除选项卡,并在添加新选项卡时用RichTextBox
填充该选项卡。
当我关闭并重新打开表单时,是否可以使用与上述方法类似的方法来保留所有选项卡的RichTextBox
数据?
...如果有道理...
这是您关于saving text box between launches的SO帖子的后续问题。我对此表示赞同,因为它涉及到许多关键点(如果您一次不学习所有这些点也可以)。 TextBox经常包含少量数据,几乎可以将其保存在任何地方。我们could通过仅在按下[Enter]键时或在TextBox失去焦点时进行保存来改进上述代码。
RichTextBox控件是不同的。它显示的文档可能很大。例如,图像(已经很大)被存储为文本流(甚至更大)。通常,使用Properties.Settings存储它是不切实际的。至于“何时保存”,我们不能依靠Enter键,因为这只是在多行控件中插入了换行符。
好消息:对于您询问的所有控件,基本流程都相同。当我们知道“我们想做什么”而不是“我们将如何做”时,我们可以制作一个带有interface关键字的待办事项列表。
interface IPersistCommon // Things we need our custom control to do.
{
SaveType SaveType { get; set; } // Possible ways to save
void Save(); // Save in the manner selected by SaveType
void Load(); // Load in the manner selected by SaveType
}
SaveType是由我们自己组成的枚举we。它描述了为我们设计的不同控件存储数据的可能方式。我们必须考虑跨WinOS,Android和iOS等平台的容量,速度和可移植性。这里有一些可能性:
enum SaveType
{
AppProperties, // Like the textbox code shown above
WindowsRegisty, // A traditional method, but Windows Only
File, // For example, an RTF file in Local AppData (cross-platform)
FileDataStore, // Mobile cross-platform
FileDataStoreJSON, // Serialize the object's content AND SETTINGS ('enabled' etc.)
SQLite // Mobile platforms also available
}
剩下的几乎太简单了!取得具有我们想要的大多数功能的控件(在本例中为RichTextBox),并使用inheritance制作一个自定义类,以添加我们在接口中声明的其他功能。这实际上迫使我们执行“待办事项”列表要求的所有内容(否则甚至无法构建)。
class PersistRichTextBox // Our own class...
: RichTextBox // ...that inherits the regular one
, IPersistCommon // ... and MUST implement SaveType, Save() and Load()
{ }
使用可浏览属性实现SaveType。
[Browsable(true)]
public SaveType SaveType { get; set; }
...通过这种方式在设计模式下可见:
对于RichTextBox,将其设置为SaveType。文件表示在实现Save方法时,将RTF数据存储在AppData文件夹的扩展名为* .rtf的文件中:
public void Save()
{
switch (SaveType)
{
case SaveType.AppProperties:
// This would be a concern if the RTF for example
// holds an image file making it gigantic.
Properties.Settings.Default[Name] = Rtf;
Properties.Settings.Default.Save();
break;
case SaveType.File:
File.WriteAllText(FileName, Rtf);
break;
case SaveType.FileDataStore:
case SaveType.FileDataStoreJSON:
case SaveType.WindowsRegisty:
case SaveType.SQLite:
default:
throw new NotImplementedException("To do!");
}
Debug.WriteLine("Saved");
}
对于RichTextBox,请从同一文件加载:
public void Load()
{
if (!DesignMode)
{
BeginInit();
switch (SaveType)
{
case SaveType.AppProperties:
Rtf = (string)Properties.Settings.Default[Name];
break;
case SaveType.File:
if(File.Exists(FileName))
{
Rtf = File.ReadAllText(FileName);
}
break;
case SaveType.FileDataStore:
case SaveType.FileDataStoreJSON:
case SaveType.WindowsRegisty:
case SaveType.SQLite:
default:
throw new NotImplementedException("To do!");
}
EndInit();
}
}
最后,至于要保存的时间,如果用户粘贴图像或按某个键,请等待大约一秒钟,以查看他们是否仍在键入。如果间隔超时后没有活动,请执行自动保存。
protected override void OnTextChanged(EventArgs e)
{
// This will pick up Paste operations, too.
base.OnTextChanged(e);
if(!_initializing)
{
// Restarts a short inactivity WDT and autosaves when done.
WDT.Stop();
WDT.Start();
}
}
// Timeout has expired since the last change to the document.
private void WDT_Tick(object sender, EventArgs e)
{
WDT.Stop();
Save();
}
......
public PersistRichTextBox() { WDT = new Timer(); WDT.Interval = 1000; WDT.Tick += WDT_Tick; } Timer WDT;
您可以从我们的GitHub存储库中clone完整的工作示例。