I have a image in window
<Image Source="{Binding Path=MYImage, Converter={StaticResource ResourceKey=imageConverter}}" />
I have also tried using a value converter:
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
return new BitmapImage(new Uri((string)value));
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and created a dependency property for it.
public string MYImage
{
get { return (string)GetValue(MYImageProperty); }
set { SetValue(MYImageProperty, value); }
}
public static readonly DependencyProperty MYImageProperty=DependencyProperty.Register("PickerImage",typeof(string),typeof(MYClass),new PropertyMetadata("/MYProject;component/pic.png"));
but when i use it, don't show image !!!
you don't have to convert the source.
you can Bind a string like that:
"/My.Namespace;component/Resources/thatsMyImage.png"
xaml:
<Image Source="{Binding Path=MYImage}" />
This is how I resolved the issue in my application.
My Application has many solutions and each solution has many projects.
I am running .NET 4.5 on VS 2012 using WPF.
My application structure is:
MyApplication
CoreSolution
-ProjectA1
-Resources
-Images
warning.ico (Build action set to Resource)
information.ico (Build action set to Resource)
error.ico (Build action set to Resource)
+ProjectA2
PersonDatabaseSolution
+ProjectB1
+ProjectB2
I have added images (actual images and not links) in CoreSolution's ProjectA1 project. I did not change the build action of any of the images. Compiled the project to get ProjectA1.dll.
In ProjectB2's PersonDatabaseSolution, I refer to error.ico in code behind using the following:
private ImageSource _myImage
public ImageSource MyImage
{
get
{
if(_myImage==null)
{
uriLoc=new Uri("pack://application:,,,/CoreSolution.ProjectA1;component/Resources/Images/error.ico", UriKInd.Absolute);
BitmapImage bmImage = new BitmapImage();
bmImage.BeginInit();
bmImage.UriSource = uriLoc;
bmImage.EndInit();
_myImage=bmImage;
}
return _myImage;
}
}
The MyImage property is bound in the xaml:
<Image Source="{Binding Path=MyImage}"/>
So far this has worked for me. Hope it helps others as well.
Thanks,
RDV
Related
I intend to create Usercontrol with boolean dependency property called IsPowerOn, When I change it True the PowerOn image load to Image.source and when I set IsPowerOn to Fals, the PowerOff image load to Image.source.
Here is my UserControl:
<UserControl x:Class="...UcPower"
...
<UserControl.Resources>
<local:PowerBoolean2Image x:Key="PowerBoolean2Image"/>
</UserControl.Resources>
<Grid>
<Image x:Name="imgPower" Source="{Binding Source, Converter={StaticResource PowerBoolean2Image}, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:UcPower}}}" />
</Grid>
And Code behind:
public static readonly DependencyProperty IsPowerOnProperty = DependencyProperty.Register("IsPowerOn", typeof(bool), typeof(UcPower),
new FrameworkPropertyMetadata(false) { BindsTwoWayByDefault = true });
public bool IsPowerOn
{
get
{
return (bool)GetValue(IsPowerOnProperty);
}
set
{
SetValue(IsPowerOnProperty, value);
}
}
And IValueConverter:
public class PowerBoolean2Image : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is bool))
{
return null;
}
if (value.Equals(true))
{
// Power On
return new BitmapImage(new Uri("pack://application:,,,/Resources/Power-On.png"));
}
else
{
// Power Off
return new BitmapImage(new Uri("pack://application:,,,/Resources/Power-Off.png"));
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
But it doesn't work I expect, whats the wrong with me?
You should bind to the IsPowerOn property:
<Image Source="{Binding IsPowerOn, ...}" />
instead of
<Image Source="{Binding Source, ...}" />
Besides that, the expression if (value.Equals(true)) looks rather strange. You could replace that by
if ((bool)value)
{
return new BitmapImage(new Uri("pack://application:,,,/Resources/Power-On.png"));
}
return new BitmapImage(new Uri("pack://application:,,,/Resources/Power-Off.png"));
or shorter:
return (bool)value
? new BitmapImage(new Uri("pack://application:,,,/Resources/Power-On.png"))
: new BitmapImage(new Uri("pack://application:,,,/Resources/Power-Off.png"));
When I use this code in IValueConverter I get Error: IOException: Cannot locate resource 'resources/power-on.png'. and cant see my form in design mode:
Uri("pack://application:,,,/Resources/Power-On.png")
But I can use Assembly name to solve the problem like this code:
Uri("pack://application:,,,/ReferencedAssembly;component/Resources/Power-On.png")
I've got a WPF application that needs to send pre-generated EMF files to a specified printer/tray.
I don't want to show the PrintDialog; the actual printer/tray is configured before hand. I also don't need to actually view the EMF file either; but rather just send it to the printer.
So far, all my R&D into this has led to is a bunch of posts that are 5 years old dealing with EMF and WPF and how it isn't supported.
Has anybody had any luck with this before? Can someone point me in the right direction?
Turns out this was easier than I thought. You can do this via a Image control, and use of a converter. This example takes the file location of the emf file, and puts it into a WPF usercontrol that I then send to a printer.
In XAML:
<Grid Margin="12">
<Image Source="{Binding Path=FileName, Converter={StaticResource emfImageConverter}, Mode=OneWay}"></Image>
</Grid>
and your converter class:
[ValueConversion(typeof(string), typeof(BitmapImage))]
public class EmfImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var fileName = (string)value;
if (fileName == null || !File.Exists(fileName))
return new BitmapImage();
using (var stream = File.Open(fileName, FileMode.Open))
{
return GetImage(stream);
}
}
internal BitmapImage GetImage(Stream fileStream)
{
var img = Image.FromStream(fileStream);
var imgBrush = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad, CreateOptions = BitmapCreateOptions.PreservePixelFormat };
imgBrush.BeginInit();
imgBrush.StreamSource = ConvertImageToMemoryStream(img);
imgBrush.EndInit();
return imgBrush;
}
public MemoryStream ConvertImageToMemoryStream(Image img)
{
var ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
I need some help to figure out why two different ways of binding an Image in XAML don't behave the same way.
Here is my code:
public class Picture
{
public int ID
{
get;
set;
}
public string ThumbURL
{
get
{
return String.Format("http://"+ App.ServerAdress +"/Pictures/thumbs/{0}.jpg", ID);
}
}
public int ThumbLocal
{
get { return ID; }
}
}
public class ByteImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
using (var store =
IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.FileExists(value)) return null;
var stream =
store.OpenFile(path, FileMode.Open);
try
{
var image = new BitmapImage();
image.SetSource(stream);
return image;
}
finally
{
stream.Dispose();
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
In case I bind the image this way, it is working:
<Image Width="110" CacheMode="BitmapCache" Source="{Binding ThumbURL}"
Margin="12,0,9,0"/>
But this way does not:
<Image Width="110" CacheMode="BitmapCache" Source="{Binding ThumbLocal, Mode=TwoWay, Converter={StaticResource imgConverter}}"
Margin="12,0,9,0"/>
This situation happens when I try to set picture from one panorama item to the other. I my case I want to add picture from one list to another and when I use first type of binding everything is working fine. Also it is working when I navigate to other page and navigate back, the picture shows up. I'm a little confused by this behavior.
Any ideas how I can solve this problem?
Finally I realized why this happened. Before Binding I have to download picture from the web and save it to the Isolated Storage, all this process is async. And in time when I Bind the picture there in no picture yet. I have try to Bind existing picture from Isolated Storage and it is correctly displayed. So, now I need something like INotifyPropertyChanged. Is any way I can do it if I use IValueConverter?
You can make it so that if the image is not in isolated storage - you start downloading the image, but return a new BitmapImage immediately and only when downloading is complete - save the image to isostore and set it as the BitmapImage's source.
Something like:
if (!store.FileExists(value))
{
var image = new BitmapImage();
ImageDownloadAndCachingHelper.DownloadImage(path, (s, e) => image.SetSource(e.ImageStream));
return image;
}
It is up to you to implement the code that converts the local path into a web URI, download it and invoke the EventHandler, where ImageDownloadedEventArgs has the ImageStream.
I need to find the way to save images to the IsolatedStorage and show them I the Silverlight (XAML)
Important: Silverlight have to take image “himself”, I cannot set the image from the code behind
I have tried many solutions before.
The very last solution is, to bind byte array and convert them to the Image
XAML
StackPanel Orientation="Horizontal" Margin="0,0,0,20">
<Image Width="110" CacheMode="BitmapCache" Source="{Binding ThumbLocal,Converter={StaticResource imgConverter}}"
Margin="12,0,9,0"/>
<StackPanel Width="311">
Code behind
public byte[] ThumbLocal
{
get;
set;
}
public class ByteImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
MemoryStream memStream = new MemoryStream((byte[])value);
memStream.Seek(0, SeekOrigin.Begin);
BitmapImage thumbLocal = new BitmapImage();
thumbLocal.SetSource(memStream);
return thumbLocal;
}
}
Everything work till I save byte[] to the database and tried to retrieve.
By now I can see the only option save image as file to the IsolatedStorage and then retrieve and covert to byte[].
Is this “smart ” solution?
First, create this converter:
public class BinaryToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value is byte[])
{
var bytes = value as byte[];
var stream = new MemoryStream(bytes);
var image = new BitmapImage();
image.SetSource(stream);
stream.Close();
return image;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Second, bind to Your byte[] using this converter, i.e. if you are using MVVM:
View:
<Image Source="{Binding IsolatedStorageImage, Converter={StaticResource BinaryToImageSourceConverter}}" x:Name="ScanImage"/>
You can make property in contrlol (prop snippet) type byte[] and read image to byte array from isostorage, then set value of property to it.
If You got more questions, feel free to ask me.
I am building a small Wpf aplication to learn myself wpf.
And i have encountered a problem with one of the controlers.
i Have an object with a list of url's in a string format, and i want to bind them to an image and use the wpf converter class to convert the url's to bitmaps.
But when i implement the converter the program throws the following error:
'XmlParseException was unhandled'
And in the details it says this:
"{"Unable to cast object of type
'ChanGrabber.Converter' to type
'System.Windows.Data.IValueConverter'."}"
This is the code for referencing the converter in the xaml:
xmlns:local="clr-namespace:ChanGrabber">
<Window.Resources>
<local:Converter x:Key="Convert"/>
</Window.Resources>
This is the code where i use the control:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ThumbImgUrl, Converter={StaticResource Convert}}" />
</StackPanel>
</DataTemplate>
and here is the code for the converter:
namespace ChanGrabber
{
class Converter
{
[valueconversion(typeof(string), typeof(bitmapimage))]
public class imageconverter : ivalueconverter
{
public object convert(object value, type targettype, object parameter, system.globalization.cultureinfo culture)
{
try
{
string mypath = (string)value;
uri myuri = new uri(mypath);
bitmapimage animage = new bitmapimage(myuri);
return animage;
}
catch (exception)
{
return new bitmapimage(new uri("ikke funket"));
}
}
public object convertback(object value, type targettype, object parameter, system.globalization.cultureinfo culture)
{
throw new notimplementedexception();
}
}
And this is is the object i am binding to the image
class MainPosts : MainLinks
{
public MainPosts(string _title, string _link, String _postText, string _imageUrl, string _thumbUrl) :base(_title,_link)
{
PostText = _postText;
ImageUrl = _imageUrl;
ThumbImgUrl = _thumbUrl;
}
public String PostText { get; set; }
public String ImageUrl { get; set; }
public string ThumbImgUrl { get; set; }
}
I have no idea why it won't work, and i am getting abit frustrated on the program.
Any help will be so incredibly appreciated
use <local:imageconverter x:Key="Convert"/>
Your converter needs to implement the IValueConverter interface, otherwise WPF won't know what to do with it (so it gives you that exception.)
class Converter : IValueConverter
{
...
}