How do I format a URI when binding an Image in Sil

2019-07-01 20:49发布

问题:

I haven't been able to find an answer to this.

I have a database that has image paths in it ("images/myimage.jpg"). These images exist on my asp.net site which is also where I host the SL. I want to bind these images to my ListBox control so that the image displays.

I have read that since I have a string value, "images/myimage.jpg", that I need to convert it to a BitMap image. I have done this:

The xaml:

 <Image Source="{Binding ImageFile, Converter={StaticResource ImageConverter}}"/>

The ImageConverter class:

    public object Convert(object value, Type targetType,
                                  object parameter, CultureInfo culture)
            {
                try
                {
                    Uri source= new Uri(value.ToString());
                    return new BitmapImage(source);
                }
                catch(Exception ex)
                {
                    return new BitmapImage();
                }
            }

I get an error when creating the URI, "The Format of the URI could not be determined". What am I doing wrong? If I create a Uri that looks like this: http://localhost:49723/images/myimage.jpg, it works just fine.

Why doesn't just "images/myimage.jpg" work?

回答1:

Relative paths to media in Silverlight are wacky so they can work the same (wacky) way that WPF paths do. Relative paths are relative to the XAP file, not the app root.

One trick is to move your XAP to the root of your website, so media paths will be relative to the root.

See my post on relative URI's in Silverlight here.



回答2:

A simple, dynamic approach that will work regardless of where your XAP file is located is similar to the following.

//Get the root path for the XAP
string src = Application.Current.Host.Source.ToString();

//Get the application root, where 'ClientBin' is the known dir where the XAP is
string appRoot = src.Substring(0,src.IndexOf("ClientBin")); 

//Create the image / uri
BitmapImage img = new BitmapImage();
img.UriSource = new Uri(appRoot + "/Images/myImage.png", UriKind.Relative);

Does this help?



回答3:

Just ran into this problem today myself and fixed it the way Jon describes above (without seeing your post though. Could have saved me some time.) I'd also point out that the specific error can be resolved by using the overload:

Uri source = new Uri("Path/Image.jpg", UriKind.Relative);

You'd still be unable to access the images subdirectory without moving the XAP file, but it resolves the error message. At that point the program just happily returns an image with no content, leaving you to use Fiddler or Web Dev Helper to figure out the real problem.



回答4:

http://www.silverlightexamples.net/post/How-to-Get-Files-From-Resources-in-Silverlight-20.aspx

Resource, and Never Copy on the image, then use "SLapplicationName;component/mypathtoimage/image.png"

using System.Windows.Resources;      // StreamResourceInfo
using System.Windows.Media.Imaging;  // BitmapImage
....

StreamResourceInfo sr = Application.GetResourceStream(
    new Uri("SilverlightApplication1;component/MyImage.png", UriKind.Relative));
BitmapImage bmp = new BitmapImage();
bmp.SetSource(sr.Stream); 


回答5:

You can simply write a method that gives you full server address (protocol://server:port/) and use it to create absolute URLs:

public class Helper{
    public static string ServerAddress{
        get{
            if (_server == "")
                _server = _ServerAddress();
            return _server;
        }
    }

     private static string _ServerAddress(){
        HttpContext ctx = HttpContext.Current;
        if (ctx == null) return "";

        HttpRequest request = ctx.Request;
        if (request == null) return "";

      string srvr = request.ServerVariables["SERVER_NAME"];
      string port = string.IsNullOrEmpty(request.ServerVariables["SERVER_PORT"])?
            "" : ":" + request.ServerVariables["SERVER_PORT"];
      string protocol = "http://";//request.ServerVariables["SERVER_PROTOCOL"];
      return string.Format("{0}{1}{2}{3}", protocol, srvr, port, 
                   request.ApplicationPath);
    }
}    

and change you Converter method line:

Uri source= new Uri(value.ToString());

to

if(!string.IsNullOrEmpty(value.ToString()))
   Uri source= new Uri(Helper.WebAddress + value.ToString());