我在各种.settings文件中存储了我的winforms程序的一大堆设置。
这些设置中包括System.Drawing.Point
,System.Drawing.Location
,System.TimeSpan
,System.DateTime
等等。
当我将表单的Location
绑定到System.Drawing.Location
并调用.Save()
方法时,一切似乎都正常。也就是说,由于似乎不需要强制转换,因此表单System.Drawing.Location
与.settings文件中存储的System.Drawing.Location
设置直接兼容。
另外,如果我说TimeSpan timeSpan = Settings.Duration;
也可以正常工作。
现在,我制作了一个大型设置表单,用户可以在其中调整各种参数,包括各种DateTime
和TimeSpan
设置。这些在TextBox
Settings DefaultSettings = Settings.Default;
TextBox1.DataBindings.Add(("Text", DefaultSettings, "Duration", false, DataSourceUpdateMode.OnValidation, new TimeSpan(00, 30, 00));
中是可见的和可编辑的,我有以下列方式绑定数据:
TimeSpan
TextBox
中可以看到Save()
,但是当我尝试编辑它并在设置数据源上调用[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("00:30:00")]
public global::System.TimeSpan StartWorkDay {
get {
return ((global::System.TimeSpan)(this["Duration"]));
}
set {
this["Duration"] = value;
}
}
时,我收到以下错误:
“0”的值对“值”无效。 “价值”应介于“最低”和“最高”之间。 参数名称:值
错误源自Visual Studio生成的代码块:
System.TimeSpan
我认为这个问题是由于它试图将字符串转换为DataBindings.Add(
以及我的.settings文件中的其他各种类而引起的。
由于我使用接受参数字符串的TextBox
绑定它们,我无法在那里强制转换或使用新关键字。
我可以在代码中手动处理它:通过逐个参数构造对象来更新设置文件,但我有很多设置存储在很多TextBoxes和NumericUpDowns中,我更喜欢只是将它们直接绑定到{{1}},假设这是可能的。
我能做到这一点的最简单方法是什么?
答案 0 :(得分:2)
你可以在Settings
类声明一个“转换属性”(我刚刚发明了那个术语):
public class Settings
{
// The real property
public TimeSpan StartWorkDay { get; set; }
// The conversion property
public string StartWorkDayString
{
get
{
return StartWorkDay.ToString();
// (or use .ToString("...") to format it)
}
set
{
StartWorkDay = TimeSpan.Parse(value);
// (or use TryParse() to avoid throwing exceptions)
}
}
}
...然后将文本框绑定到该文本框。
答案 1 :(得分:2)
我在一个示例Windows窗体应用程序中尝试了以下代码,它没有任何例外地进行了保存。
// Define the settings binding source
private System.Windows.Forms.BindingSource settingsBindingSource;
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.durationTextBox = new System.Windows.Forms.TextBox();
this.settingsBindingSource = new BindingSource(this.components);
this.settingsBindingSource.DataSource = typeof(WindowsFormsApplication1.Properties.Settings);
this.durationTextBox.DataBindings.Add(new Binding("Text", this.settingsBindingSource, "Duration", true));
}
// In the form load event where the textbox is displayed
private void Form1_Load(object sender, System.EventArgs e)
{
settingsBindingSource.DataSource = Settings.Default;
}
// save button click
private void button1_Click_1(object sender, System.EventArgs e)
{
// This saved the settings, without any exceptions
Settings.Default.Save();
}
希望它有所帮助。
答案 2 :(得分:0)
我想出了一个你可能感兴趣的优雅解决方案:
由于问题似乎是我无法使用数据绑定从简单的文本框中转换或构建.settings文件中的数据类型,而是制作了一些自定义控件。
例如,TimeSpans现在使用我TimeSpanPicker
控件生成的DateTimePicker
,其中日期已禁用,上/下切换为开启,Value
属性为从选择器控件中转换为TimeSpan。
这种方法的另一个优点是我不需要在使用文本框之前进行大量的验证,因为TimeSpanPicker基本控件DateTimePicker只显示有效时间。我需要做的很少的验证可以在Set {}属性中完成,所以我不需要定义事件处理程序。
这似乎运作良好! 现在,我需要做的就是用自定义控件替换所有文本框。