【问题标题】:Why does the exact same code produce different results?为什么完全相同的代码会产生不同的结果?
【发布时间】:2012-12-26 09:15:25
【问题描述】:

在这段代码之后:

    if ((App.roamingSettings.Values.ContainsKey("FromMonthSection1")) &&
        (!string.IsNullOrWhiteSpace(App.roamingSettings.Values["FromMonthSection1"].ToString())))
    {
        comboBoxFromMonth.SelectedValue = App.roamingSettings.Values["FromMonthSection1"].ToString();
    }
    if ((App.roamingSettings.Values.ContainsKey("FromDaySection1")) &&
        (!string.IsNullOrWhiteSpace(App.roamingSettings.Values["FromDaySection1"].ToString())))
    {
        comboBoxFromDay.SelectedValue = App.roamingSettings.Values["FromDaySection1"].ToString();
    }

...按预期运行,comboBoxFromMonth 的 SelectedValue = "August"。但是,comboBoxFromDay 的 SelectedValue = null,即使在即时窗口中,我也看到了:

App.roamingSettings.Values["FromDaySection1"].ToString()
"16"
comboBoxFromDay.Items.Count
31

单步执行,赋值语句在两种情况下都运行,只是由于某种原因,comboxFromDay.SelectedValue 为 null,即使在赋值之后也是如此。

那么,使用完全相同的代码会导致这些相反反应的不同之处是什么?

有问题的两个组合框的 xaml 是:

<ComboBox x:Name="comboBoxFromMonth" Height="24" Width="100" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="4" LostFocus="ComboBox_OnLostFocus" ></ComboBox>

<ComboBox x:Name="comboBoxFromDay" Grid.Row="1" Grid.Column="1" Height="24" Width="80" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="2" LostFocus="ComboBox_OnLostFocus"/>

XAML 在所有实际用途上都完全相同,除了 comboBoxFromMonth 没有明确的 Grid.Row 或 Grid.Column 分配。

另外,漫游值的设置也是一样的:

if (cmbxName == "comboBoxFromMonth")
{
    App.roamingSettings.Values["FromMonthSection1"] =
        comboBoxFromMonth.SelectedValue;
}
else if (cmbxName == "comboBoxFromDay")
{
    App.roamingSettings.Values["FromDaySection1"] =
        comboBoxFromDay.SelectedValue;
}

那么它是如何在一种情况下起作用而在另一种情况下不起作用的呢?

顺便说一句,在“属性”窗格中查看的两​​个组合框的属性也相同(当然,名称除外;还有 MaxDropDownHeight - 520 与 Infinity,但我确信这无关紧要)。

已解决(或者我认为)

布兰登一针见血:删除“.ToString()”:

if ((App.roamingSettings.Values.ContainsKey("FromDaySection1")) &&
    (!string.IsNullOrWhiteSpace(App.roamingSettings.Values["FromDaySection1"].ToString())))
{
    comboBoxFromDay.SelectedValue = App.roamingSettings.Values["FromDaySection1"];
}

...有效。

更新

好吧,毕竟还没有完全解决;我注意到了一些奇怪的事情:

漫游设置引擎显然决定了您要保存的值的数据类型。

如果您保存诸如“January”之类的值,它会将其保存为字符串。 如果您保存诸如“1”到“12”之类的值,它会将其保存为 int。

但是,如果您有诸如“00”(适当地视为字符串)之类的值和诸如“10”到“59”之类的值,该怎么办?虽然存储在同一个存储桶中(例如,“ToMinuteSection1”),但数据类型会发生变化。

这是有道理的,因为桶一次只有一个值。如果是“00”,则视为字符串;如果它是“10”,则它被视为一个 int。

但这使得在检索这些值时有点笨拙,因为如果“ToMinuteSection1”中包含的值是一个字符串(例如“00”),这会起作用:

comboBoxToMinute.SelectedValue = App.roamingSettings.Values["ToMinuteSection1"].ToString();

...但如果该值被视为 int(例如“59”),则不是;那么它必须是:

comboBoxToMinute.SelectedValue = App.roamingSettings.Values["ToMinuteSection1"];

所以...因为我不知道用户会选择什么,所以我可以这样做,但似乎我应该为此被扇耳光:

int toMinute;
string toMinuteStr = App.roamingSettings.Values["ToMinuteSection1"].ToString();
bool isInt = int.TryParse(toMinuteStr, out toMinute);
if (isInt) // it should alway be an int now
{
    if (toMinute < 10)
    {
        comboBoxToMinute.SelectedValue = toMinuteStr;
    }
    else
    {
        comboBoxToMinute.SelectedValue = toMinute;
    }
}

...实际上,我首先尝试这样做:

int toMinute;
string toMinuteStr = App.roamingSettings.Values["ToMinuteSection1"].ToString();
bool isInt = int.TryParse(toMinuteStr, out toMinute);
if (isInt)
{
    comboBoxToMinute.SelectedValue = toMinute;
}
else
{
    comboBoxToMinute.SelectedValue = toMinuteStr;
}

...但是这个技巧不起作用,因为“09”被解析成9就好了,但是赋值为空,因为组合框中没有“9”,只有一个“09”

有没有更优雅的方法来完成这个(比我上面显示的我的 slapworthy 方法)?

【问题讨论】:

    标签: c# combobox winrt-xaml windows-store-apps


    【解决方案1】:

    组合框中的值是整数还是字符串?根据MSDN Documentation 上的备注,如果您为 SelectedValue 设置的值不在组合框中,则它会清除选择(即将其设置为 null)。如果它们是整数,则您的 ToString() 可能找不到匹配项。

    【讨论】:

      【解决方案2】:

      由于您遇到不同的问题,我不知道最好是添加新答案还是编辑我之前的答案。既然你问的是不同的问题,我认为添加新答案更有意义,但我会让模组整理出来。

      根据您的描述,听起来您的组合框实际上可能只包含整数 0 - 59,但您希望它们全部显示为 2 位数字(任何小于 10 的都应该有前导零)。

      如果是这种情况,请查看 ComboBox 上的 ItemStringFormat 属性。请原谅我说的很明显,但这可以让您指定一个格式字符串来显示组合框中的项目。您可以使用标准的 .NET 格式字符串来指定前导零,并且只需使用整数来填充组合框。希望这能解决您的“类型变形”问题。

      【讨论】:

      • 是的,对于某些条目,我确实想要前导“0”(例如分钟);不过,不确定 ItemStringFormat 应该是什么。
      • Google ".NET Format Strings" 你应该找到大量的文档来帮助你弄清楚:) 如果你是格式化字符串的新手,我建议你下载 LINQPad 作为尝试小程序的一种方式段 C# 代码只是为了看到它,而不需要创建一个全新的 VS 项目或修改您的应用程序代码。我一直使用它来测试格式字符串、正则表达式和一些我还不想放入程序中的逻辑。
      • 另外,请注意在 XAML 中指定格式字符串有一些怪癖,例如需要以某种方式转义 { 和 } 字符。我已经有一段时间没有做这件事了,所以我不记得细节了,但是有很多关于它的谷歌点击和 SO 问题,所以应该不难找到。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多