【问题标题】:User settings reads wrong double type value用户设置读取错误的双精度类型值
【发布时间】:2016-12-29 09:47:39
【问题描述】:

我正在尝试制作一个用于编辑用户设置的应用程序并遇到了一个奇怪的问题。我正在使用user settings 读写,但它无法读取其中一个变量。

    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);
    }

和 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。 Botch 范围设置为用户。

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

我尝试添加 MessageBox.Show(Properties.Settings.Default.input1Setting.ToString()) 在启动时,它仍然显示 1,但是 app.config 中 input1 的值(在 project/bin/debug/ 文件夹中的那个,在 local/company/project/1.0.0/ 和 Visual Studio app.config 中的那个是4)

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

【问题讨论】:

  • 尝试在设置文件中将 input1 设置为 4.0
  • @arbitrarystringofletters 没有帮助
  • 表单的初始化可能会导致问题。您可以尝试将设置的值写入控制台而不是显示MessageBox 吗?在Main(string[] args) 之后尝试此操作:Console.WriteLine(Properties.Settings.Default.input1Setting);,然后让控制台保持打开状态:Console.Read();
  • 您在哪里/如何将值设置为 4?如果您使用存储在 Properties.Settings.Default.input1Setting 中的值,并且它显示为 1,您为什么认为它应该不同?您似乎没有正确设置设置。

标签: c# wpf settings


【解决方案1】:

问题 input1 的最小值不为零,并且 ValueChanged 在 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"/>

并在 InitializeComponent 之后添加它们,最好在设置值之后添加它们,这样您就不会重新保存现有值:

  input1.ValueChanged += input1_ValueChanged;
  input2.ValueChanged += input2_ValueChanged;

选项 2

但是,根据您的查看方式,更好的选择是将控件直接绑定到设置,然后仅在关闭表单时调用 save。

通过将 Settings 键放在 app.xaml 文件中,确保它可用。您需要将命名空间添加到 Application 节点属性,xmlns:properties="clr-namespace:WpfApplication1.Properties" 并在 Application.Resourses 节点中添加属性节点。以下是您的 app.xaml 的外观示例(使用通用命名空间):

<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>

现在回到您的 MainWindow.xaml,删除 ValueChanged(如上例所示)并添加一个将其绑定到设置值的 Value 属性:

<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"/>

然后在您的 MainWindow.xaml.cs 文件中将其修改为如下所示:

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);
}

当然,如果您更喜欢在 XAML 中连接您的事件,您可以跳过 Closing += MainWindow_Closing;在 MainWindow.xaml.cs 文件中,而是将这个 Closing="MainWindow_Closing" 属性添加到 MainWindow.xaml 的 Window 节点。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多