C# 用户设置读取错误的双精度类型值

C# 用户设置读取错误的双精度类型值,c#,wpf,settings,C#,Wpf,Settings,我试图制作一个用于编辑用户设置的应用程序,但遇到了一个奇怪的问题。我用它来写和读,它不能读取其中一个变量 public MainWindow() { InitializeComponent(); input1.Value = Properties.Settings.Default.input1Setting; input2.Value = Properties.Settings.Default.input2Setting;

我试图制作一个用于编辑用户设置的应用程序,但遇到了一个奇怪的问题。我用它来写和读,它不能读取其中一个变量

    public MainWindow()
    {
        InitializeComponent();

        input1.Value = Properties.Settings.Default.input1Setting;
        input2.Value = Properties.Settings.Default.input2Setting;
    }


    private void input1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        Properties.Settings.Default.input1Setting = Convert.ToDouble(input1.Value);
        Properties.Settings.Default.Save();
    }

    private void input2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        Properties.Settings.Default.input2Setting = Convert.ToInt16(input2.Value);
        Properties.Settings.Default.Save();
    }

    private void OnlyNumberValidation(object sender, TextCompositionEventArgs e)
    {
        Regex regex = new Regex("[^0-9]+");
        e.Handled = regex.IsMatch(e.Text);
    }
public主窗口()
{
初始化组件();
input1.Value=Properties.Settings.Default.input1Setting;
input2.Value=Properties.Settings.Default.input2Setting;
}
私有void input1\u值已更改(对象发送方,RoutedPropertyChangedEventArgs e)
{
Properties.Settings.Default.input1Setting=Convert.ToDouble(input1.Value);
Properties.Settings.Default.Save();
}
私有void输入2_值已更改(对象发送方,RoutedPropertyChangedEventArgs e)
{
Properties.Settings.Default.input2Setting=Convert.ToInt16(input2.Value);
Properties.Settings.Default.Save();
}
私有void OnlyNumberValidation(对象发送方,TextCompositionEventArgs e)
{
正则表达式正则表达式=新正则表达式(“[^0-9]+”);
e、 Handled=regex.IsMatch(e.Text);
}
和xaml滑块

<Slider ValueChanged="input1_ValueChanged" IsSnapToTickEnabled="True" TickFrequency="0.25" Minimum="1" Maximum="50" Name="input1" PreviewTextInput="OnlyNumberValidation"/>
<Slider ValueChanged="input2_ValueChanged" IsSnapToTickEnabled="True" TickFrequency="1" Maximum="2000" Minimum="0" Name="input2" PreviewTextInput="OnlyNumberValidation"/>

在visual studio设置编辑器中,input1设置为double,input2设置为int。这两个作用域都设置为user

问题是,只有滑块input2获得正确的值。input1始终设置为1

我试图添加MessageBox.Show(Properties.Settings.Default.input1Setting.ToString()) 启动时,它仍然显示1,但app.config中的input1值(project/bin/debug/folder中的input1值,local/company/project/1.0.0/和visualstudio app.config中的input1值为4)


upd1将4更改为4.0没有帮助。仍然更改为1。

问题是input1的最小值为非零,并且在XAML中设置了更改后的值。创建滑块时,默认情况下滑块的值为零,然后将事件连接起来,然后将滑块调整为最小值和最大值

这意味着input1上的值更改为1,然后触发事件并将值保存到设置中。这一切都发生在InitializeComponent期间,因此发生在您尝试在MainWindow的构造函数中分配input1.Value之前

选项1

有几个选项,首先是对现有代码的更改更少。从XAML中删除ValueChanged绑定

<Slider IsSnapToTickEnabled="True" TickFrequency="0.25" Minimum="1" Maximum="50" Name="input1" PreviewTextInput="OnlyNumberValidation"/>
<Slider IsSnapToTickEnabled="True" TickFrequency="1" Maximum="2000" Minimum="0" Name="input2" PreviewTextInput="OnlyNumberValidation"/>
选项2

但更好的选择可能是直接将控件绑定到设置,然后仅在关闭表单时调用save,这取决于您的查看方式

通过将设置密钥放置在app.xaml文件中,确保其可用。您需要将名称空间添加到应用程序节点属性xmlns:properties=“clr namespace:WpfApplication1.properties”中,并在Application.resources节点内部添加属性节点。下面是app.xaml的示例(使用通用名称空间):

当然,如果您希望在XAML中连接事件,您可以跳过关闭+=main窗口\u关闭;在MainWindow.xaml.cs文件中,而是将Closing=“MainWindow\u Closing”属性添加到MainWindow.xaml的窗口节点

我喜欢选项2,因为它只保存一次,即使是设置。默认值始终基于滑块值可用,您只需保存它,以便下次启动时可用


试试这些,看看你更喜欢哪一个。

问题是input1的最小值不为零,并且在XAML中设置了更改的值。创建滑块时,默认情况下滑块的值为零,然后将事件连接起来,然后将滑块调整为最小值和最大值

这意味着input1上的值更改为1,然后触发事件并将值保存到设置中。这一切都发生在InitializeComponent期间,因此发生在您尝试在MainWindow的构造函数中分配input1.Value之前

选项1

有几个选项,首先是对现有代码的更改更少。从XAML中删除ValueChanged绑定

<Slider IsSnapToTickEnabled="True" TickFrequency="0.25" Minimum="1" Maximum="50" Name="input1" PreviewTextInput="OnlyNumberValidation"/>
<Slider IsSnapToTickEnabled="True" TickFrequency="1" Maximum="2000" Minimum="0" Name="input2" PreviewTextInput="OnlyNumberValidation"/>
选项2

但更好的选择可能是直接将控件绑定到设置,然后仅在关闭表单时调用save,这取决于您的查看方式

通过将设置密钥放置在app.xaml文件中,确保其可用。您需要将名称空间添加到应用程序节点属性xmlns:properties=“clr namespace:WpfApplication1.properties”中,并在Application.resources节点内部添加属性节点。下面是app.xaml的示例(使用通用名称空间):

当然,如果您希望在XAML中连接事件,您可以跳过关闭+=main窗口\u关闭;在MainWindow.xaml.cs文件中,而是将Closing=“MainWindow\u Closing”属性添加到MainWindow.xaml的窗口节点

我喜欢选项2,因为它只保存一次,即使是设置。默认值始终基于滑块值可用,您只需保存它,以便下次启动时可用


试试这些,看看你更喜欢哪一个。

试着在设置文件中将input1设置为
4.0
。@ArriryStringOfLetters没有帮助表单的初始化可能会导致问题。是否可以尝试将放样值写入控制台,而不是显示
消息框
?在
Main(string[]args)
之后尝试此操作:
Console.WriteLine(Properties.Settings.Default.input1Setting)
然后让控制台保持打开状态:
console.Read()在何处/如何将值设置为4?如果您使用的是存储在Properties.Settings.Default.input1Setting中的值,并且它显示为1,那么为什么您认为它应该有所不同?您似乎没有正确设置设置。请尝试在设置文件中将input1设置为
4.0
。@ArriryStringOfLetters没有帮助表单的初始化可能会失败
<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication1"
             xmlns:properties="clr-namespace:WpfApplication1.Properties"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <properties:Settings x:Key="Settings" />
  </Application.Resources>
</Application>
<Slider IsSnapToTickEnabled="True" TickFrequency="0.25" Minimum="1" Maximum="50" Name="input1" Value="{Binding Source={StaticResource Settings}, Path=Default.input1Setting}" PreviewTextInput="OnlyNumberValidation"/>
<Slider IsSnapToTickEnabled="True" TickFrequency="1" Maximum="2000" Minimum="0" Name="input2" Value="{Binding Source={StaticResource Settings}, Path=Default.input2Setting}" PreviewTextInput="OnlyNumberValidation"/>
public MainWindow()
{
  InitializeComponent();
  Closing += MainWindow_Closing;
}

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
  Properties.Settings.Default.Save();
}

private void OnlyNumberValidation(object sender, TextCompositionEventArgs e)
{
  Regex regex = new Regex("[^0-9]+");
  e.Handled = regex.IsMatch(e.Text);
}