разрабатываю приложение, но мне необходимо из ресурсов достать изображение по средством языка C# без xaml. XAML не подходит из-за того, что в будущем путь к картинки будет динамическим и само изображение сможет загружать пользователь, но при отсутствии заданного фона программа сама из ресурсов достанет картинку. В итоге получается, что вместо картинки черный фон, но не могу понять из-за чего, ведь все построено вроде логично, но не прокатывает. Сам файл "Background" имеет действие при сборке "Resource" и имеет расширение jpg.
Основной класс (Привязанный к xaml интерфейсу):
WindowState = WindowState.Maximized;
ImageBrush imageBrush = new ImageBrush()
{
ImageSource = Source.Image.ConvertBitmapToImageSource(Properties.Resources.Background),
};
this.Background = imageBrush;
Класс, отвечающий за преобразование ресурса:
public static ImageSource ConvertBitmapToImageSource(Bitmap value)
{
using (MemoryStream ms = new MemoryStream())
{
value.Save(ms, ImageFormat.Jpeg);
BitmapImage img = new BitmapImage();
img.BeginInit();
ms.Seek(0, SeekOrigin.Begin); img.StreamSource = ms;
img.EndInit();
return img;
}
}
XAML в вашей задаче как раз и нужен, еще как!
image-not-found.png
в корне проекта.Дальше в ресурсах укажем BitmapImage
с нужным изображением. Я для простоты и скорости написания примера укажу это прям в ресурсах главного окна:
<Window.Resources>
<BitmapImage x:Key="NotFoundImage" UriSource="image-not-found.png" />
</Window.Resources>
Теперь нам нужно создать свойство, которое будет содержать путь к нужному изображению и так, как оно будет обновляться, нам нужно реализовать еще и INotifyPropertyChanged
:
Добавляем события INPC:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string prop = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
Добавляем публичное string
свойство:
private string backgroundPath;
public string BackgroundPath
{
get => backgroundPath;
set
{
backgroundPath = value;
OnPropertyChanged();
}
}
Указываем DataContext
к классу, где реализовали свойство (у меня это само окно (опять же скорость и все дела, делать там не стоит!):
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
Теперь вернемся к XAML и сделаем там простенький интерфейс:
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="{Binding BackgroundPath, FallbackValue={StaticResource NotFoundImage}}" Width="500" Stretch="UniformToFill" />
<TextBox Grid.Row="1" Text="{Binding BackgroundPath, UpdateSourceTrigger=PropertyChanged}" BorderThickness="0 0 0 1"/>
</Grid>
Тут как видите текстовое поле привязано к созданному свойству и изображение. У изображения установлен FallbackValue
, который при проблемах с установкой значения выдаст нам картинку из ресурсов. Тут можно также указать и TargetNullValue={StaticResource NotFoundImage}
, тогда "заглушка" будет устанавливаться еще и тогда, когда привязанное свойство будет NULL
.
Хорошо, можем теперь запускать и тестировать:
Вот и все. Как видите без всяких проверок и большого кода с конветациями, мы привязали путь к изображению и его "заглушку" из ресурсов.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
//Здесь я вывожу рандомное событие, можно ли как то лучше написать этот код?