如何在两次启动之间保留 RichTextBox 数据?
How do I persist RichTextBox data between launches?
嗨,我是一名新程序员,感谢我的另一个问题中的一个人的帮助。通过此方法关闭和重新打开应用程序时,我设法保留了 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();
}
当我关闭并重新打开表单时,是否有办法让我使用与 RichTextBox
类似的东西?
这是对您的 SO post 关于 的一个很好的后续问题。我赞成它,因为它触及了很多关键点(如果你不一次学习所有这些也没关系)。 TextBox 通常包含的数据量非常小,几乎可以轻松保存在任何地方。我们可以通过仅在按下 [Enter] 键或 TextBox 失去焦点时保存来改进上述代码。
RichTextBox 控件不同。它显示的文档可能非常大。例如,图像(已经很大)存储为文本流(更大)。一般用Properties.Settings来存储是不实用的。就 "when to save" 而言,我们不能依赖 Enter 键,因为它只是将换行符插入到多行控件中。
好消息:对于您询问的所有控件,基本流程是相同的。当我们知道 "what we want to do" 但不知道 "how we're going to do it" 时,我们可以制作一个具有关键字 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 是一个枚举我们 自己编造的。它描述了为我们设计的不同控件存储数据的可能方法。我们必须考虑跨平台(如 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 以添加我们在界面中声明的附加功能.这实际上迫使我们实现我们的待办事项列表要求的一切(否则它甚至不会构建)。
class PersistRichTextBox // Our own class...
: RichTextBox // ...that inherits the regular one
, IPersistCommon // ... and MUST implement SaveType, Save() and Load()
{ }
使用 Browsable 属性实现 SaveType。
[Browsable(true)]
public SaveType SaveType { get; set; }
...这样它在设计模式中可见:
对于 RichTextBox,将其设置为 SaveType。File 表示在我们实现 Save 方法时将 AppData 文件夹中的 RTF 数据存储在扩展名为 *.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();
}
}
最后,就 "when" 保存而言,如果用户粘贴图像或按下某个键,请等待大约一秒钟以查看他们是否仍在输入。如果在间隔超时后没有活动,则进行自动保存。
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 完整的工作示例。
嗨,我是一名新程序员,感谢我的另一个问题中的一个人的帮助。通过此方法关闭和重新打开应用程序时,我设法保留了 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();
}
当我关闭并重新打开表单时,是否有办法让我使用与 RichTextBox
类似的东西?
这是对您的 SO post 关于
RichTextBox 控件不同。它显示的文档可能非常大。例如,图像(已经很大)存储为文本流(更大)。一般用Properties.Settings来存储是不实用的。就 "when to save" 而言,我们不能依赖 Enter 键,因为它只是将换行符插入到多行控件中。
好消息:对于您询问的所有控件,基本流程是相同的。当我们知道 "what we want to do" 但不知道 "how we're going to do it" 时,我们可以制作一个具有关键字 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 是一个枚举我们 自己编造的。它描述了为我们设计的不同控件存储数据的可能方法。我们必须考虑跨平台(如 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 以添加我们在界面中声明的附加功能.这实际上迫使我们实现我们的待办事项列表要求的一切(否则它甚至不会构建)。
class PersistRichTextBox // Our own class...
: RichTextBox // ...that inherits the regular one
, IPersistCommon // ... and MUST implement SaveType, Save() and Load()
{ }
使用 Browsable 属性实现 SaveType。
[Browsable(true)]
public SaveType SaveType { get; set; }
...这样它在设计模式中可见:
对于 RichTextBox,将其设置为 SaveType。File 表示在我们实现 Save 方法时将 AppData 文件夹中的 RTF 数据存储在扩展名为 *.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();
}
}
最后,就 "when" 保存而言,如果用户粘贴图像或按下某个键,请等待大约一秒钟以查看他们是否仍在输入。如果在间隔超时后没有活动,则进行自动保存。
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 完整的工作示例。