Часто при создании сообщений для показа пользователю сообщение будет содержать ряд вещей, о которых я хочу сообщить клиенту.
Я приведу пример: клиент выбрал несколько элементов от 1 и выше и нажал кнопку «Удалить». Теперь я хочу отправить покупателю подтверждающее сообщение и упомянуть количество выбранных им элементов, чтобы свести к минимуму вероятность того, что он совершит ошибку, выбрав несколько элементов и нажав кнопку «Удалить», когда он хочет удалить только один из них. их.
Один из способов - сделать общее сообщение таким:
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";
«Проблема» здесь в том, что noofitemselected
это 1, и мы должны написать item и it вместо items и них .
Мое обычное решение будет примерно таким
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";
Это становится довольно длинным и довольно неприятным, очень быстро, если в коде много ссылок на множество чисел, а фактическое сообщение становится трудно читать.
Так что мои вопросы просты. Есть ли лучшие способы создания подобных сообщений?
РЕДАКТИРОВАТЬ
Я вижу, что многие люди очень зациклились на том случае, когда я упомянул, что сообщение должно отображаться внутри окна сообщения, и просто дал ответ о том, как вообще избежать использования окна сообщения, и это все хорошо .
Но помните, что проблема множественного числа также относится к текстам в других местах программы, помимо окон сообщений. Например, метка рядом с сеткой, отображающая количество строк, выбранных в сетке, будет иметь ту же проблему в отношении множественного числа.
Таким образом, это в основном относится к большей части текста, который каким-то образом выводится из программ, и тогда решение не так просто, как просто изменить программу, чтобы текст больше не выводился :)
источник
Ответы:
Если есть шанс, даже самый маленький, что это приложение нужно будет перевести на другие языки, то оба они ошибаются. Правильный способ сделать это:
Это связано с тем, что разные языки по-разному обрабатывают множественность. Некоторые, такие как малайский, даже не имеют синтаксических множественных чисел, поэтому строки обычно идентичны. Разделение двух строк упрощает поддержку других языков в дальнейшем.
В противном случае, если это приложение предназначено для широкой публики и должно быть удобным для пользователя, предпочтительнее второй метод. Извините, но я не знаю более короткого способа сделать это.
Если это приложение предназначено для использования только внутри вашей компании, сделайте это с помощью ярлыка
"item(s)"
. При написании предприимчивого кода не нужно никого впечатлять. Но я бы не советовал делать это для общедоступных приложений, потому что это создает впечатление, что программист ленив, и, таким образом, снижает их мнение о качестве приложения. Поверьте мне, такие мелочи имеют значение.источник
noofitemsselected
этом примере вы даже можете оптимизировать первый вариант; поскольку вы знаете, что это 1.Вы можете избежать всего этого беспорядочного множества, просто удалив элементы без какого-либо сообщения и предоставив пользователю действительно хорошую возможность отмены. Пользователи никогда ничего не читают . В любом случае вы должны создать хорошую возможность отмены как часть своей программы.
На самом деле вы получаете 2 преимущества, когда создаете комплексную возможность отмены. Первое преимущество облегчает жизнь пользователя, позволяя ему исправить ошибки и свести к минимуму чтение. Второе преимущество заключается в том, что ваше приложение отражает реальную жизнь, позволяя отменить нетривиальный рабочий процесс (а не только ошибки).
Однажды я написал приложение без единого диалогового окна или подтверждающего сообщения. Это потребовало серьезного размышления и было значительно труднее реализовать, чем использование сообщений типа подтверждения. Но конечный результат был довольно приятным для использования конечными пользователями.
источник
Как насчет только:
Таким образом вы устраняете трудности с согласованием номеров и получаете в качестве бонуса еще более короткое и конкретное сообщение об ошибке для пользователя. Все мы знаем, что пользователи все равно не читают сообщения об ошибках . Чем они короче, тем больше вероятность, что они хотя бы взглянут на текст.
Или, зная, что пользователи не читают сообщения об ошибках, вы можете подойти к этому по-другому. Полностью пропустите подтверждающее сообщение и просто предоставьте функцию отмены, которая работает, независимо от того, что было удалено. Большинство пользователей уже привыкли отменять операцию, когда замечают, что это было не то, что они хотели, и, вероятно, сочтут такое поведение более естественным, чем иметь дело с очередным раздражающим всплывающим окном.
источник
А как насчет того, что было в Java на протяжении многих лет: java.text.MessageFormat и ChoiceFormat? См. Http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html для получения дополнительной информации.
В вашем случае вам нужно что-то попроще:
Преимущество этого подхода заключается в том, что он хорошо работает с пакетами i18n, и вы можете правильно предоставлять переводы для языков (например, японского), которые не имеют понятия слова во множественном или единственном числе.
источник
Я бы не стал жестко кодировать сообщение, но предоставил два сообщения в отдельном файле ресурсов. подобно
а затем подавать их в String.Format, например
Я думаю, что такой подход проще локализовать и поддерживать. Все сообщения пользовательского интерфейса будут в одном месте.
источник
Вы можете полностью обойти проблему, сформулировав сообщение иначе.
источник
Первое, что я предлагаю: использовать
string.Format
. Это позволяет делать что-то вроде этого:Кроме того, в приложениях WPF я встречал системы, в которых строка ресурса была бы разделена каналом, чтобы иметь два сообщения: единственное и множественное сообщение (или даже сообщение ноль / одно / много). Затем можно использовать настраиваемый конвертер для анализа этого ресурса и использования соответствующей (отформатированной) строки, поэтому ваш Xaml будет примерно таким:
источник
Для английского много ответов выше. Для других языков это сложнее, так как множественное число зависит от рода существительного и окончания слова. Некоторые примеры на французском:
Обычный мужской род:
Обычный женский
Нерегулярный мужской род (заканчивается буквой s)
Та же проблема существует в большинстве латинских языков и усугубляется в немецком или русском, где есть 3 пола (макулиновый, женский и средний).
Вам нужно будет позаботиться о том, чтобы заниматься не только английским языком.
источник
Я считаю, что для того, чтобы иметь возможность иметь множественные сообщения, которые можно будет правильно локализовать, было бы разумно сначала создать уровень косвенного обращения между номером и сообщением.
Например, используйте какую-либо константу, чтобы указать, какое сообщение вы хотите отобразить. Получите сообщение, используя некоторую функцию, которая скроет детали реализации.
Затем создайте словарь, содержащий возможные сообщения и варианты, и укажите варианты, когда их следует использовать.
Теперь вы можете просто найти ключ, который соответствует,
quantity
и интерполировать значениеquantity
с этим сообщением.Это упрощенный и наивный пример, но я действительно не вижу другого разумного способа сделать это и обеспечить хорошую поддержку L10N и I18N.
источник
Вам нужно будет перевести приведенную ниже функцию с VBA на C #, но ваше использование изменится на:
У меня есть функция VBA, которую я использую в MS Access, чтобы делать именно то, о чем вы говорите. Я знаю, что меня разобьют на куски за публикацию VBA, но все равно здесь. Алгоритм должен быть очевиден из комментариев:
Использование было немного отключено в комментариях к коду выше, поэтому я повторю его здесь:
Да, это решение игнорирует языки, кроме английского. Будет ли это иметь значение, зависит от ваших требований.
источник
Вы можете автоматически сгенерировать множественное число, см. Например. множественный генератор .
Правила формирования множественного числа см. В Википедии.
источник
Как насчет более общего способа. Избегайте множественного числа во втором предложении:
Я обнаружил, что таким образом число ставится в конец строки, что очень легко заметить. Это решение будет работать с той же логикой на любом языке.
источник
Number
(я отвечал, пока качал ребенка спать).Мой общий подход - написать "единственную / множественную функцию", например:
Затем в теле сообщения я вызываю эту функцию:
Это ненамного лучше, но, по крайней мере, он (а) помещает решение в функцию и, таким образом, немного освобождает код, и (б) достаточно гибок, чтобы обрабатывать неправильные множественные числа. т.е. достаточно легко произнести существительное (сущ., «ребенок», «дети») и тому подобное.
Конечно, это работает только для английского языка, но эту концепцию легко распространить на языки с более сложными окончаниями.
Мне пришло в голову, что вы можете сделать последний параметр необязательным для простого случая:
источник
Интернационализация
Я предполагаю, что вам нужна поддержка интернационализации, и в этом случае разные языки имеют разные шаблоны для множественного числа (например, специальная форма множественного числа для 2 чего-то или более сложные языки, такие как польский), и вы не можете полагаться на применение какого-то простого шаблона к вашей строке Исправить это.
Вы можете использовать
ngettext
функцию GNU Gettext и добавить в исходный код два сообщения на английском языке. Gettext предоставит инфраструктуру для выбора других (потенциально большего количества) сообщений при переводе на другие языки. См. Http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html для полного описания поддержки множественного числа GNU gettext.GNU Gettext находится под лицензией LGPL.
ngettext
названGettextResourceManager.GetPluralString
в порте C # Gettext.(Если вам не нужна поддержка локализации и вы не хотите сразу использовать Gettext, тогда напишите свою собственную функцию, которая делает это для английского языка, и передайте ей два полных сообщения , таким образом, если вам понадобится l10n позже, вы можете добавить, переписав одну функцию.)
источник
Как насчет написания функции вроде
.. и использовать его, когда вам нужно?
источник
Для первой проблемы, я имею в виду Pluralize, вы можете использовать Inflector .
А для второго вы можете использовать расширение строкового представления с таким именем, как ToPronounString.
источник
Вчера один из наших сотрудников задал мне точно такой же вопрос.
Поскольку он снова появился здесь, на StackOverflow, я подумал, что вселенная говорит мне, что я должен попытаться создать достойное решение.
Я быстро собрал что-то воедино, и это ни в коем случае не идеально, но это может быть полезно или вызвать обсуждение / развитие.
Этот код основан на идее, что может быть 3 сообщения. Один для нуля элементов, один для одного элемента и один для более чем одного элемента, которые имеют следующую структуру:
singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural
Я создал внутренний класс для тестирования, чтобы имитировать класс ресурсов. Я еще не тестировал это с использованием фактического файла ресурсов, поэтому мне еще предстоит увидеть полный результат.
Вот код (в настоящее время я включил несколько обобщений, где я знаю, что мог бы указать третий параметр просто как тип, а также второй параметр - это строка, я думаю, что есть способ объединить эти два параметра во что-то лучшее, но я ' Я вернусь к этому, когда у меня будет свободное время.
Класс тестового ресурса:
и мой метод быстрого выполнения
источник
singlePropertyName_All
чтобы сделать это еще более очевидным.С моей точки зрения, ваше первое решение является наиболее подходящим. Я говорю, что если вам нужно, чтобы приложение поддерживало несколько языков, второй вариант может оказаться утомительным. При первом подходе текст легко локализовать без особых усилий.
источник
Вы можете использовать более общее сообщение, например: «Вы действительно хотите удалить выбранные элементы».
источник
Я зависит от того, насколько красивое сообщение вы хотите передать. От простого к сложному:
Перепишите сообщение об ошибке, чтобы избежать множественного числа. Не так приятно для пользователя, но быстрее.
Используйте более общий язык, но все же включайте число (а).
Используйте систему "множественного числа" и инфлекторную систему, как Rails, чтобы вы могли сказать
pluralize(5,'bunch')
и получить5 bunches
. У Rails есть хороший шаблон для этого.Для интернационализации вам нужно посмотреть, что предоставляет Java. Это будет поддерживать широкий спектр языков, в том числе те, которые имеют разные формы прилагательных с 2 или 3 элементами. Решение "s" очень ориентировано на английский язык.
Какой вариант вы выберете, зависит от целей вашего продукта. - ндп
источник
Почему вы хотите представить сообщение, которое действительно могут понять пользователи? Это идет вразрез с 40-летней историей программирования. Нееееет, у нас хорошие дела, не портите их понятными сообщениями.
(Дж / К)
источник
Сделайте так, как это сделано в World of Warcraft:
источник
Он становится немного короче с
источник
Один из подходов, о котором я не упоминал, - это использование тега замены / выбора (например, что-то вроде «Вы собираетесь раздавить {0} [? I ({0} = 1): / cactus / cacti /]». (другими словами, укажите в выражении, подобном формату, замену на основе того, равен ли нулевой аргумент, взятый как целое число, 1). Я видел такие теги, использованные в дни до .net; я не знаю ни одного стандарт для них в .net, и я не знаю лучшего способа их отформатировать.
источник
Я бы подумал на минуту прямо из коробки, все предложения здесь либо включают множественное число (и беспокоятся о более чем 1 уровне множественного числа, пола и т. Д.), Либо не используют его вообще и обеспечивают хорошую отмену.
Я бы пошел неязычным путем и использовал для этого визуальные очереди. Например, представьте, что в приложении для Iphone вы выбираете элементы, вытирая палец. перед удалением их с помощью основной кнопки удаления, он «встряхнет» выбранные элементы и покажет вам вопросительный знак с заголовком с кнопками V (ок) или X (отмена) ...
Или, в трехмерном мире Kinekt / Move / Wii - представьте, что вы выбираете файлы, перемещаете руку к кнопке удаления и вам приказывают поднять руку над головой для подтверждения (используя те же визуальные символы, что я упоминал ранее. Например, вместо попросить вас удалить 3 файла? он покажет вам 3 файла с парящим полупрозрачным красным X и скажет вам сделать что-то для подтверждения.
источник