在应用程序关闭时保存按钮文本、路径和图标

本文关键字:文本 路径 图标 按钮 保存 应用程序 | 更新日期: 2023-09-27 18:33:59

我做了一个小程序,可以启动应用程序(比如任务栏中的快速启动(您可以添加应用程序,它会显示.exe的图标和文件名,当您单击它(按钮(时,它会启动应用程序。

当您关闭程序并重新启动它时,一切都是空的,所以我想将其保存在某个地方。

我看到互联网上的人这样做:

    private void QuickStarter_FormClosed(object sender, FormClosedEventArgs e)
    {
        Properties.Settings.Default.Button1 = button1.Text;
        Properties.Settings.Default.Save();
    }
    private void QuickStarter_Load(object sender, FormClosedEventArgs e)
    {
        button1.Text = Properties.Settings.Default.Button1;
    }

这不起作用,但他们将其用于文本字段和输入框,我不知道按钮是否可能。

问题:有人可以告诉我保存按钮输入并在应用程序再次启动时将其重新加载的最佳方法是什么?或者也许我必须用标签或其他东西来做?

我使用的一些小片段:

   private void QuickStarter_Load(object sender, FormClosedEventArgs e)
    {
        button1.Text = Properties.Settings.Default.Button1;
    }
    Icon ico = null;
    OpenFileDialog ofd = new OpenFileDialog();
    string[] fileNames = new string[5];
    private void application1ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        ofd.Filter = "EXE|*.exe";
        ofd.Title = "Add application";
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            ico = Icon.ExtractAssociatedIcon(ofd.FileName);
            button1.Text = Path.GetFileNameWithoutExtension(ofd.FileName);
            button1.Image = ico.ToBitmap();
            button1.Enabled = true;
            fileNames[0] = ofd.FileName;
        }
    }
    private void button1_Click(object sender, System.EventArgs e)
    {
        ProcessStartInfo start = new ProcessStartInfo();
        start.FileName = fileNames[0];
        Process.Start(start);
    }
    private void QuickStarter_FormClosed(object sender, FormClosedEventArgs e)
    {
        Properties.Settings.Default.Button1 = button1.Text;
        Properties.Settings.Default.Save();
    }
}

在应用程序关闭时保存按钮文本、路径和图标

验证投诉

使用以下代码对我来说效果很好,单击按钮将

设置新文本,关闭并重新加载应用程序将告诉我上次单击按钮的时间。

    private void Form1_Load(object sender, EventArgs e) {
        button1.Text = Settings.Default.button1;
    }
    private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
        Settings.Default.button1 = button1.Text;
        Settings.Default.Save();
    }
    private void button1_Click(object sender, EventArgs e) {
        button1.Text = string.Format("Button was clicked at {0}", DateTime.Now);
    }

应用程序权限可能有问题,如果不允许写入 %appdata% 子文件夹,则无法存储设置。
但也完全有可能您的解决方案中存在其他问题。从您的描述中无法立即清楚。创建一个最小的测试项目(就像我所做的那样(,并验证您无法保存和检索全新测试项目的设置。

回答您的问题

每当你问一些类似What is the optimal way to ...的事情时,你都不会得到一个决定性的答案,如果我对Stack Overflow有所了解,我会说当你提出问题时,我会说这是不鼓励的。

也就是说,这就是我会这样做的方法。

  1. 创建实现可序列化属性的数据对象的集合。请参见 XML 序列化简介
  2. 该集合将保存使用Point结构描述按钮、文本、可执行文件及其位置(如果适用(的属性。
  3. 我会在加载时反序列化它并在关闭时序列化它(或者更好的是,当某些东西发生变化时(
  4. 我会(反序列化后(迭代该集合中的数据对象并在运行时动态创建按钮,将它们添加到FormControls中,如下所示:
    Controls.Add(new Button { Text = "This is a new button!"});
  5. 我还会添加一些控件来添加/删除数据对象集合中的条目。或者通过使用上下文菜单,无论哪种方式都有效。您的设计,您的决定。
  6. 随着您对编码更有信心,您可以继续拖放按钮以对它们进行排序或将它们放置在"快速启动"应用程序中。

您需要将 button1 属性添加到 Settings.Designer 中的设置.cs(或使用 Settings.settings 网格。

您还需要确保在窗口关闭时触发"QuickStarter_FormClosed"事件。

这是我的设置设计器.cs:

namespace SettingsSaveTest.Properties {

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
    public static Settings Default {
        get {
            return defaultInstance;
        }
    }
    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("")]
    public string ButtonText {
        get {
            return ((string)(this["ButtonText"]));
        }
        set {
            this["ButtonText"] = value;
        }
    }
}

}我没有注意到它是针对Windows窗体的,而不是WPF,但是同样的事情适用,您需要将该属性添加到您的settings.designer中。

这是我在Windows窗体中的版本:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
       button1.Text = Properties.Settings.Default.button1;
    }
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        button1.Text = "Saving...";
    }
    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        SaveProperties();
    }
    private void SaveProperties()
    {
        Properties.Settings.Default.button1 = textBox1.Text;
        Properties.Settings.Default.Save();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        button1.Text = textBox1.Text;
    }
}

我还将 FormClosed 事件处理程序添加到 FormClosed 堆栈中:

this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);

我也为WPF留下了答案,因为其他人可能会想知道。但同样的事情也适用。您需要添加属性,并配置事件侦听器。

这是我的主窗口.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Button1.Content = Properties.Settings.Default.ButtonText;
        Closed += SaveSettings;
    }
    private void SaveSettings(object sender, EventArgs e)
    {
        SaveProperties();
    }
    private void SaveProperties()
    {
        Properties.Settings.Default.ButtonText = UserInput.Text;
        Properties.Settings.Default.Save();
    }
    private void Button1_Click(object sender, RoutedEventArgs e)
    {
       SaveProperties();
       Button1.Content =  Properties.Settings.Default.ButtonText;
    }
}

最后是我的MainWindow.xaml

<Window x:Class="SettingsSaveTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox x:Name="UserInput" x:FieldModifier="public" HorizontalAlignment="Left" Height="23" Margin="48,105,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
    <Button x:Name="Button1" Content="Button" HorizontalAlignment="Left" Margin="203,105,0,0" VerticalAlignment="Top" Width="75" Click="Button1_Click"/>
</Grid>