2

我将一个文本框绑定到一个类的成员,我需要调整电话号码的外观,以便更容易阅读(用户不想看到诸如“1234567890”或“+01234567890”之类的值)。所以,我有这个代码:

var bindingPhone = new Binding("Text", platypusInfo, "Phone1", true);
bindingPhone.Format += phoneBinding_Format;
textBoxPhoneNum1.DataBindings.Add(bindingPhone);

...

private void phoneBinding_Format(object sender, ConvertEventArgs e) {
    e.Value = ??How can I deal with this??
}

但是电话值,虽然通常“NNNNNNNNNN”(例如“1234567890”)或“+NNNNNNNNNN”(例如“+01234567890”)也可以出现在许多其他排列中,例如:

 (NN) NNNN NNNN
++NNNNNNNNNNNNN
+NNNNNNNNNNNNN
+NN NNNNNNNNNNN
NNNNNNNNNNNN

我可以在 phoneBinding_Format() 中做些什么来使这些电话号码更易于阅读,而不会将它们分成无意义的部分,例如“43-4859-4365”而不是“434-859-4365”?

更新

由于这些因素:

1)我同时在做几个项目,需要回到另一个项目 2)我们的两种最常见的格式占我们电话号码的最大份额 3)这只是一个“不错的功能”而不是“必须拥有”特征

...根据 Jon Skeet 的回答,我现在已经确定了以下内容:

private void phoneBinding_Format(object sender, ConvertEventArgs e)
{
    const int UK_PHONE_LEN = 9;                     // +NNNNNNNN 
     const int US_PHONE_FORMAT_LEN = 10;             // NNNNNNNNNN
    const int COMMON_INTERNATIONAL_FORMAT_LEN = 12; //+NNNNNNNNNNN 

    string phone;
    string area;
    string major;
    string minor;
    string intl_firstsegment;
    string intl_secondsegment;
    string intl_thirdsegment;
    string intl_fourthsegment;
    string intl_fifthsegment;

    if (e.Value.ToString().Length == US_PHONE_FORMAT_LEN)
    {
        phone = e.Value.ToString();
        area = phone.Substring(0, 3);
        major = phone.Substring(3, 3);
        minor = phone.Substring(6);
        e.Value = string.Format("{0}-{1}-{2}", area, major, minor); 
    } 
else if ((e.Value.ToString().Length == UK_PHONE_LEN) && (e.Value.ToString()[0] == '+')) {
    phone = e.Value.ToString();
    intl_firstsegment = phone.Substring(0, 2);
    intl_secondsegment = phone.Substring(2, 3);
    intl_thirdsegment = phone.Substring(5);
    e.Value = string.Format("+{0}-{1}-{2}", intl_firstsegment, intl_secondsegment, intl_thirdsegment);
} 
else if ((e.Value.ToString().Length == COMMON_INTERNATIONAL_PHONE_LEN) && (e.Value.ToString()[0] == '+')) 
    {
        phone = e.Value.ToString();
        intl_firstsegment = phone.Substring(0, 2);
        intl_secondsegment = phone.Substring(2, 2);
        intl_thirdsegment = phone.Substring(4, 3);
        intl_fourthsegment = phone.Substring(7, 2);
        intl_fifthsegment = phone.Substring(9);
        e.Value = string.Format("+{0}-{1}-{2}-{3}-{4}", intl_firstsegment, intl_secondsegment, intl_thirdsegment, intl_fourthsegment, intl_fifthsegment);
    }
}

顺便说一句,在断点必杀技的路上发生了一件有趣的事情:我最初将这些测试(第一个字符是加号,长度是预期的)颠倒过来,得到:System.IndexOutOfRangeException 未被用户代码处理 Message=Index 在数组的边界。

反转条件以便首先检查长度(当长度为 0/字符串为空时自然不会失败)修复它(此后不再尝试访问 char 0)。

4

5 回答 5

7

如果您想支持除美国(以及与美国 100% 兼容的加拿大)号码之外的国际电话号码, Google 的LibPhoneNumber可能正是您所需要的。

Google 的通用 Java、C++ 和 Javascript 库,用于解析、格式化、存储和验证国际电话号码。Java 版本针对在智能手机上运行进行了优化,自 4.0(Ice Cream Sandwich)起就被 Android 框架使用。

从 C# 使用它:

http://blog.thekieners.com/2011/06/06/using-googles-libphonenumber-in-microsoft-net-with-c/

C# 端口

https://bitbucket.org/pmezard/libphonenumber-csharp/wiki/Home

于 2012-07-17T17:44:40.020 回答
2

最简单的方法是在应用格式之前从字符串中删除所有非数字字符和空格。

http://msdn.microsoft.com/en-us/library/844skk0h.aspx

于 2012-07-17T17:38:37.437 回答
1

有趣的代码片段在这里。可用于在显示电话号码之前对其进行美化。

Input: xxxxxxxxxx or xxx-xxx-xxxx or (xxx) xxx-xxxx, Output: (xxx) xxx-xxxx

代码

private string formatPhoneNumber(string number) {
    System.Text.RegularExpressions.Regex pattern = new System.Text.RegularExpressions.Regex("^\\(?([1-9]\\d{2})\\)?\\D*?([1-9]\\d{2})\\D*?(\\d{4})$");
    Match re = Regex.Match(number, pattern.ToString());
    return "(" + Convert.ToString(re.Groups[1]) + ") " + Convert.ToString(re.Groups[2]) + "-" + Convert.ToString(re.Groups[3]);
}
于 2012-07-17T17:38:01.897 回答
1

我个人会指定只允许数字电话号码(这意味着用户可能不会输入电话号码,如 1-800-FLOWERS),然后在格式化之前去除所有非数字字符。

于 2012-07-17T17:38:15.737 回答
1

我得到的是,您有以十位字符格式(“1234567890”)存储的数字,没有格式化,但现在您需要添加格式以使数字更具可读性,而不会使数字对于该数字所在的国家/地区无意义由于不同国家/地区对号码的默认格式不同,区号、中心局和用户的 (ACD) COX-SUBS 的 NANPA 系统并不总是适用。

我的建议是维护一个电话号码掩码表或字典,然后使用 MaskedTextBox 并将号码和掩码绑定到联系人对象中的数据。

例如,电话掩码 ID 1 可能用于 NANPA 号码:“000-000-0000”。电话掩码 ID 2 可能用于伦敦地铁号码,为“\000 0000 0000”(前导数字始终为零,从国外拨打电话时应省略)。ID 3 可能用于法国电话号码:“00 00 00 00 00”。您可以在对象上指定一个“仅获取”属性,该属性将向文本框提供实际的掩码字符串,并绑定一个不同的控件(可能是下拉菜单),用户可以选择以正确的格式显示数字(您可以保存以供该联系人以后使用)。大多数情况下,您可以根据国家/地区进行猜测,但情况并非总是如此。

了解您将需要很多口罩,而且它们并不总是十位数。虽然 NANPA 系统相对一致,但英国的电话号码却一团糟;地理区号是可变长度的,总数可以是十位或十一位,因此根据地理区号,英国号码有六种不同的掩码。在墨西哥,区号可​​以是两位或三位,总数为十位。法国电话号码是十位数字,每两个一组。此外,要拨打的实际数字组合取决于您从哪里拨打电话;如果呼叫始终来自美国,许多欧洲号码系统会放弃用于国内呼叫的前导零,而是拨打国家/地区代码。

于 2012-07-17T18:20:53.810 回答