Страницы

Поиск по вопросам

четверг, 9 апреля 2020 г.

Странная ошибка в XAML: ошибка при конвертации типа при присваивании через StaticResource

#c_sharp #wpf #xaml

                    
Не знал как коротко описать суть проблемы.

Вот код xaml


    
        
    
    
        
    



Вот код c# класса LocalizedString

public class LocalizedString : IComparable, ICloneable, IEnumerable, IEquatable,
IEquatable
{
    public LocalizedString(string str)
    {
        OriginalString = str;
    }

    public LocalizedString()
    {
        OriginalString = "";
    }

    public string OriginalString { get; set; }

    public string LocalizeString
    {
        get
        {
            return InteractiveLocalizer.Localize(OriginalString);
        }
    }

    public override string ToString()
    {
        return LocalizeString;
    }

    public int CompareTo(object obj)
    {
        if (obj == null)
            return 1;
        var str = obj as string;
        if (str != null)
            return LocalizeString.CompareTo(str);
        var lstr = obj as LocalizedString;
        if (lstr != null)
            return LocalizeString.CompareTo(lstr.LocalizeString);
        throw new ArgumentException("LocalizedDtring: Bad type");
    }

    public object Clone()
    {
        return new LocalizedString(OriginalString);
    }

    public IEnumerator GetEnumerator()
    {
        return LocalizeString.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Equals(string other)
    {
        return other == LocalizeString || other == OriginalString;
    }

    public bool Equals(LocalizedString other)
    {
        return OriginalString == other.OriginalString;
    }

    public static implicit operator LocalizedString(string v)
    {
        return new LocalizedString(v);
    }

    public static explicit operator String(LocalizedString ls)
    {
        return ls.LocalizeString;
    }
}


В данном случае LocalizedString ворачивает ту же самую строку, что и получает "qwe".
Я это и ожидал, но во время выполнения прога падает с исключением. Вот текст 


  "qwe" не является допустимым значением для свойства "Text".


Как так? 

Ошибка есть и во время компиляции (хоть она и позволяет запуститься приложению).
Вот ее текст


  Не удается применить объект типа "LocalizerLib.LocalizedString" к
  свойству, для которого требуется тип "System.String".


В классе определены операторы implict и explict. Чего еще не хватает, чтобы я мог
вместо string вставить свой тип?
    


Ответы

Ответ 1



XAML игноирирует операторы приведения типа (хоть явные, хоть неявные). Разнообразные конвертеры используются, например, для преобразования результатов биндинга. И даже в этом случае операторы не используются, предпочтение отдаётся ассоциированному TypeConverter (который, впрочем, по умолчанию поддерживает преобразование к строке и просто вызывает ToString). Однако при использовании ресурсов никакой конвертации не производится. Ваш код приводит к вызову: object res = new LocalizedString("foo"); fooTextBlock.Text = res; С очевидными последствиями. Могу предложить несколько путей: Вместо странных костылей с ресурсами можно воспользоваться расширениями разметки MarkupExtension. Метод ProvideValue может возвращать произвольный тип и даже учитывать, какому свойству какого объекта значение сейчас присваивается. Выглядеть это в XAML будет кратко и естественно: Продолжать городить костыли, но заставить XAML вызвать конвертеры: Вообще-то в WPF встроены средства для локализации, но кому до них дело... P. S. Код не тестировал, мог наврать.

Комментариев нет:

Отправить комментарий