Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изображения в локализованном ресурсе 
:(
    Опции темы
Compositum
Дата 25.3.2010, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Разбираюсь с локализацией по статьям первая и вторая.
Изучил первую статью, попробовал - получается. Но... Локализовывать может потребоваться не только текстовую часть GUI, но и др. тип информации - например изображения. Предположим, что у меня в окне должен отображаться флаг страны, чья локализация является текущей. 

Для этого в файл Resources.resx я добавил нужный мне файл изображения,  и в его свойствах задал Name = flag и Persistence = Embedded in .resx. 

Теперь хочу в XAML-разметке окна сослаться на этот ресурс. Как это правильно сделать? У меня не получается выполнить это и из кода:

user posted image

Из скрина видно, что поток (объект ms) не равен null, однако pngImg.StreamSource равен null, хотя я присвоил ему значение ms. Что я не верно сделал?


PM   Вверх
Compositum
Дата 25.3.2010, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: 1
Всего: 1



В общем из кода нужно делать как-то так (это ежели кому интересно):
Код

        public Window1()
        {
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");            
            InitializeComponent();
            Bitmap png = Properties.Resources.flag;
            using (MemoryStream ms = new MemoryStream())
            {
                png.Save(ms, ImageFormat.Png);
                BitmapImage bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.StreamSource = ms;
                bitmap.EndInit();
                bitmap.Freeze();

                Img.BeginInit();
                Img.Source = bitmap;
                Img.EndInit();                
            }
        }

Так же на тему багов BitmapImage.StreamSource можно прочитать здесь

А можно ли выполнить привязку из XAML- разметки? И ещё момент:
если xaml-описание такое:
Код

<Image Name="Img" Margin="2" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center" Height="20" />

То изображение флажка такое:

user posted image

Однако если убрать значение Height:
Код

<Image Name="Img" Margin="2" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"/>

то получаю такую штуку:

user posted image

Я хочу, чтобы размер изображения автоматически подстраивался под размер png-источника.

Это сообщение отредактировал(а) Compositum - 25.3.2010, 13:22
PM   Вверх
Compositum
Дата 26.3.2010, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: 1
Всего: 1



можно конечно сделать так:
Код

        public Window1()
        {
            //Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");            
            InitializeComponent();
            Bitmap png = Properties.Resources.flag;
            using (MemoryStream ms = new MemoryStream())
            {                
                png.Save(ms, ImageFormat.Png);
                BitmapImage bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.StreamSource = ms;
                bitmap.EndInit();
                bitmap.Freeze();

                Img.BeginInit();
                Img.Source = bitmap;
                Img.Height = png.Height;
                Img.Width = png.Width;
                Img.EndInit();                
            }
        } 

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

Это сообщение отредактировал(а) Compositum - 26.3.2010, 11:02
PM   Вверх
Compositum
Дата 26.3.2010, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Написал простенький конвертер:
Код

    [ValueConversion(typeof(Bitmap), typeof(BitmapImage))]
    public class BitmapConverter : IValueConverter
    {
        #region IValueConverter Members
        /// <summary>
        /// Конвертор объекта Bitmap в объект BitmapImage
        /// </summary>
        /// <param name="value">Конвертируемый объект класса Bitmap</param>
        /// <param name="targetType">Поскольку тип, в который конвертируется значение заранее известен, 
        /// то в данноый параметр следует передавать null.</param>
        /// <param name="parameter">Параметр должен являться перечислением типа ImageFormat</param>
        /// <param name="culture">Значение культуры в данном случае не важно - можно указать null</param>
        /// <returns></returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if ((value.GetType() == typeof(Bitmap)))
            {
                if (parameter.GetType() == typeof(ImageFormat))
                {
                    Bitmap png = (Bitmap) value;
                    using (MemoryStream ms = new MemoryStream())
                    {
                        png.Save(ms, (ImageFormat)parameter);
                        BitmapImage bitmapImg = new BitmapImage();
                        bitmapImg.BeginInit();
                        bitmapImg.CacheOption = BitmapCacheOption.OnLoad;
                        bitmapImg.StreamSource = ms;                        
                        bitmapImg.EndInit();
                        bitmapImg.Freeze();
                        return bitmapImg;              
                    }
                }
                else
                {
                    throw new Exception("Передаваемый параметр должен иметь тип ImageFormat");
                }
            }
            else
            {
                throw new Exception("Конвертируетмый объект должен иметь тип Bitmap");
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Подправил программный код конструктора окна:
Код

       public Window1()
        {
            //Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");            
            InitializeComponent();
            Bitmap png = Properties.Resources.flag;
            BitmapConverter cnv = new BitmapConverter();
            Img.Source = (BitmapImage) cnv.Convert(png,null,ImageFormat.Png, null);
        }

В этом случае всё будет работать как надо: появляется окошко с изображением локализованного флага, причём флаг имеет реальные размеры изображения. Т.е. всё пучком... Но... я ведь хочу всё это реализовать исключительно через разметку XAML... А значит вышеуказанный фрагмент кода откладываю в сторону...

В ресурсах приложения прописываю конвертер:
Код

<Application x:Class="Localization1.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:localize="clr-namespace:Localization1"
    xmlns:props="clr-namespace:Localization1.Properties"
    xmlns:sys="clr-namespace:System.Drawing;assembly=System.Drawing"
    StartupUri="Window1.xaml">
    <Application.Resources>
        <localize:BitmapConverter x:Key="converter"/>        
    </Application.Resources>
</Application>


Подправил xaml-код, касающийся Image (указал привязки, чтобы изображение не раздувалось на всё окно, а так же прописал привязку источника изображения (свойство Source): 
Код

        <Image Name="Img" Margin="2" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
               Source="{Binding Source={x:Static res:Resources}, Path=flag, Converter ={StaticResource converter}, ConverterParameter=Png}"

В результате получаю ошибки:
Цитата


Exception has been thrown by the target of an invocation.
'res:Resources' member is not valid because it does not have a qualifying type name.
    Localization1

В принципе, я понимаю в чём тут ошибка - указан res:Resources, а xaml ожидает получить не просто класс, а статический объект, т.е. в моём случае это должно быть res:Resources.flag. Но тогда получается, что я уже непосредственно указываю на то свойство, которое мне нужно и в параметр Path мне уже нечего передавать... Я пробовал такой вариант:
Код

        <Image Name="Img" Margin="2" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
               Source="{Binding Source={x:Static res:Resources.flag}, Path=x:Null, Converter ={StaticResource converter}, ConverterParameter=Png}"

никаких ошибок не возникает, но и никакого флага в окошке не появляется...




Это сообщение отредактировал(а) Compositum - 26.3.2010, 22:32
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.0489 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.