WPF ValueConverter - стандартный возврат необратимого значения - PullRequest
42 голосов
/ 13 мая 2011

В течение последнего года или около того я видел много разных преобразователей значений для разных целей, от разных авторов.Одна вещь, которая мне запомнилась, - это большая дисперсия значений по умолчанию, которые они возвращают.Например;

  public class MyConverter: IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      // OK, we test for some undesirable, unconvertable situation, typically null...
      if (value == null)
      {
        // And here are a variety of 'defaults' that I have seen, these begin the most typical.
        return null;
        return DependencyProperty.UnsetValue;
        return Binding.DoNothing;
      }
        //...... other code.. whatever...
}}

Итак, мой вопрос, есть ли «стандартный» способ указать, что входное значение не может быть преобразовано?

Ответы [ 6 ]

26 голосов
/ 10 октября 2011

В соответствии с MSDN - IValueConverter :

Механизм привязки данных не перехватывает исключения, создаваемые предоставленным пользователем преобразователем.Любое исключение, которое выдается методом Convert, или любые неперехваченные исключения, которые выдают методы, которые вызывает метод Convert, рассматриваются как ошибки времени выполнения.Обработка ожидаемых проблем путем возврата DependencyProperty.UnsetValue .

Строка ключа Обработка ожидаемых проблем путем возврата DependencyProperty.UnsetValue.

23 голосов
/ 13 мая 2011

Когда вы посмотрите на эти значения, вы поймете, что они значат.Затем выберите правильный вариант для возврата в конвертере.

Основная проблема заключается в том, что для свойства допустимым может быть значение null.

DependencyProperty.UnsetValue , чтобы указать, чтосвойство существует, но его значение не установлено системой свойств

Binding.DoNothing , чтобы указать механизму привязки не передавать значение в цель привязки, а не перемещаться вnext Binding в PriorityBinding или не использовать FallBackValue или значение по умолчанию

EDIT

Чтобы указать, что вы не можете преобразовать значение, вы должны просто вернуть заданное значениезначение.Это лучшее, что вы можете сделать, потому что это возвращает проблему автору связывания.Если вы вмешиваетесь в это значение, становится очень трудно выяснить, что происходит.

5 голосов
/ 07 октября 2011

После долгих раздумий и размышлений кажется, что DependencyProperty.UnsetValue является подходящим выбором. Я переместил все в доме к этому образцу с большим успехом. Кроме того, текст в разделе «Замечания» на этой странице указывает на то, что, вероятно, это лучший выбор.

Существует также некоторое обсуждение возврата входного значения, если привязка не может быть преобразована, но это может легко "сломать" систему привязки. Подумайте о случае, когда входным связыванием является «строка», а выходным - «кисть». Возврат строки не сработает!

2 голосов
/ 13 мая 2011

то, что вы возвращаете по умолчанию, зависит от ситуации.Вы не хотите возвращать int как значение по умолчанию для конвертера в bool или возвращать bool для конвертера для перечисления видимости.

1 голос
/ 07 октября 2011

Обычно, если значение не может быть преобразовано, я выбрасываю Exception

Это потому, что если я пытаюсь преобразовать значение с использованием недопустимого конвертера, я хотел бы получить уведомление об этом, чтобы я мог изменить свой код.

В некоторых редких случаях значение может быть допустимым, даже если оно не может быть преобразовано, и в этом случае я обычно возвращаю то же значение, которое было передано в преобразователь. Это используется, только если я хочу, чтобы значение было преобразовано, если это возможно, или осталось прежним, если нет.

Другой редкий случай, который я иногда делал, это жесткое кодирование значения по умолчанию. Обычно это делается, когда я знаю, что конвертер может использоваться с недопустимым параметром, и я хочу вернуть действительное значение независимо от того, каков результат. Мои жестко запрограммированные конвертеры по умолчанию почти всегда возвращают логические значения.

Не думаю, что я когда-либо возвращал 3 из указанных вами (null, DependencyProperty.UnsetValue или Binding.DoNothing), потому что эти значения часто бывают неожиданными и их нелегко заметить, если вы специально не ищите их.

0 голосов
/ 13 мая 2011

Вы также можете вернуть реальный targetType объект по умолчанию, используя эту функцию:

public static object GetDefault(Type type)
{
   if(type.IsValueType)
   {
      return Activator.CreateInstance(type);
   }
   return null;
}

Источник: C # - Программный эквивалент значения по умолчанию (Тип)

...