IValueConverter поддерживать состояние, если не удается установить параметр преобразователя


У меня есть IValueConverter, который преобразует значение enum в локализованную строку через таблицу подстановки и наоборот. Чтобы найти правильную таблицу, сначала нужно знать ее название. Когда значение enum передается в конвертер с помощью метода Convert, это можно найти. Когда строка передается в конвертер с помощью метода ConvertBack, это не так (типы enum уникальны, но строковые значения-нет).

Конвертер используется на DataTemplates для используемых редакторов в таблице данных и таблице свойств.

В одном случае можно передать имя таблицы в качестве преобразователя Parameter, так как DataTemplate динамически генерируется. В другом случае это кажется невозможным. Мое текущее решение ищет имя таблицы в методе Convert и сохраняет его для использования в методе ConvertBack (т. е. IValueConverter поддерживает состояние между вызовами Convert и ConvertBack). Это предполагает, что Convert всегда будет вызываться до ConvertBack, что не кажется безопасным предположением. Я использую в обязательный экземпляр конвертера:

<converters:EnumToStringConverter x:Key="EnumToStringConverter" x:Shared="False"/>
Это безопасно или это вернется, чтобы преследовать меня? Методы преобразования выглядят следующим образом:
private string listName = null;

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (parameter == null)
    {
        parameter = ListManager.FindListNameFromObject(value);
    }
    listName = (string)parameter;
    return ListManager.GetKeyFromValue((string)parameter, value);
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{

    if (parameter == null)
    {
        parameter = listName;
    }
    return ListManager.GetValueFromKey((string)parameter, (string)value);
}

Альтернативой, которую я пытался увидеть, если это возможно, является создание свойства зависимости от конвертера и привязка его к имени коллекции каким-либо образом. Есть ли способ установить DataContext конвертера таким же, как и привязка, на которую он действует? В настоящее время конвертер-это StaticResource, поэтому у него нет DataContext.

Спасибо

2 4

2 ответа:

Converters не разрешается быть DependencyObjects в WPF, так как они не смогут обеспечить привязку к своим свойствам, которые могут динамически изменяться.

Код ниже преобразует Key в Value & Value к Key с помощью динамически привязанного Dictionary.

XAML

 <StackPanel>
   <StackPanel.Resources>
      <FrameworkElement x:key="ProxyElement" 
                        DataContext="{Binding}" />
   </StackPanel.Resources>
   <ContentControl Visibility="Collapsed" 
                   DataContext="{Binding MyDictionary}"
                   Content="{StaticResource ProxyElement}" />
   <TextBox Text="{Binding Key, 
                           Converter={StaticResource MyConverter},
                           ConverterParameter={StaticResource ProxyElement}}"/>
 </StackPanel>

C#

 public class MyConverter : IValueConverter
 {
     object Convert(value, parameter ..)
     {
          var dict 
              = ((FrameworkElement)parameter).DataContext 
                  as Dictionary<string, string>)parameter;
          return (dict[value.ToString()];
     }

     object ConvertBack (value, parameter ..)
     {
        var dict 
              = ((FrameworkElement)parameter).DataContext 
                  as Dictionary<string, string>)parameter;

        foreach(var item in dict)
        {
            if (item.Value == value)
            {
                return item.Key;
            }
        }
     }
 }

Вы всегда можете привязать свое значение к just "."это тогда дало бы вам ваш DataContext в конвертере, тогда вы могли бы сохранить состояние в этом объекте вместо этого.