Image.Location variant for WPF? - c#

I'm a noob when it comes to WPF; In win forms I can do this:
public void blah()
{
using( var o = new OpenFileDialog())
{
if(o.ShowDialog() == DialogResult.OK)
{
PictureBox p = new PictureBox();
p.ImageLocation = o.FileName;
p.AutoSize = SizeMode.AutoSize;
this.Controls.Add(p);
}
}
}
But in WPF I have no idea at all and not even MSDN will give me any clear info on how to insert a pic onto the form at runtime! Can someone please help?
Thank you very much

Basically you need to create a System.Windows.Controls.Image and set its Source to a System.Windows.Media.Imaging.BitmapImage. Then add the image to the Children of the Container. You may want to put the image inside of another container first like a Canvas. Here's a quick translation of your code, but you'll likely need to play with it a bit to get it just right.
public void blah()
{
using( var o = new OpenFileDialog())
{
if(o.ShowDialog() == DialogResult.OK)
{
Image i = new Image();
i.Source = new BitmapImage(o.FileName);
//p.AutoSize = SizeMode.AutoSize; <= not sure about this part.
this.Children.Add(i);
}
}
}

You could use XAML and some bindings (and possibly a converter to convert a string to an image source). It's more in keeping with the WPF way of doing things.
Example without converter:
XAML
<Window
...
x:Name="this"
DataContext="{Binding ElementName=this}">
<Grid>
<ListView ItemsSource="{Binding MyImageCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>
Code Behind
public class Window1 : Window {
public ObservableCollection<ImageSource> MyImageCollection { get; set; }
...
public void blah()
{
using( var o = new OpenFileDialog())
{
if(o.ShowDialog() == DialogResult.OK)
{
MyImageCollection.Add(new BitmapImage(new Uri(o.FileName)));
}
}
}
}

Here is an easier way to do it.
Image.Source = new BitmapImage(new Uri("C:\MyImage.jpg");

Related

How can I use Listbox items with WPF?

I am trying to learn Wpf.
When the program runs, it gives me the "no listbox source" error.
I am working on a Wpf design but I just started.
The features I have added to the listbox externally, how can I show them as sources. I have no idea about this. I think I have been researching this for 2 hours but I have not found any answer. I have some problems with English. I hope I won't bother you. All details of my codes are below.
Thank you in advance for helping.
//Note : My Class : (public partial class MainWindow : Window)
public void btnListAdd_Click(object sender, RoutedEventArgs e)
{
CronList1.Items.Clear(); // ListBox <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
OpenFileDialog f = new OpenFileDialog();
if (f.ShowDialog().HasValue == true)
{
List<string> lines1 = new List<string>();
using (StreamReader r = new StreamReader(f.OpenFile()))
{
string line;
while ((line = r.ReadLine()) != null)
{
CronList1.Items.Add(line); // ListBox <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
}
}
}
2 : I then try to read all in the CronList. I run the method in the class.
CronEvent cronEvent = new CronEvent();
Task.Run(cronEvent.Cron1);
3 :My Code Dont Run!
public async Task Cron1()
{
int sayix = 1;
while (true)
{
try
{
(HttpWebRequest) rq WebRequest.Create(mainWindow.CronList1.Items[sayix].ToString());
rq .Proxy = WebRequest.GetSystemWebProxy();
rq .AllowAutoRedirect = false;
rq .Timeout = 10000;
HttpWebResponse rply= (HttpWebResponse)rq.GetResponse();
StreamReader streamReader = new StreamReader(rply.GetResponseStream());
rply.Close();
streamReader.Close();
mainWindow.CronList1.SelectedIndex = sayix;
sayix++;
if (sayix == mainWindow.CronList1.Items.Count)
{
sayix = 0;
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
await Task.Delay(TimeSpan.FromSeconds(Convert.ToDouble(mainWindow.txtTime.Text)));
}
}
WPF Listbox Code
<ListBox Name="CronList1" Height="390" Margin="2,7,4,0" VerticalAlignment="Top" BorderBrush="Red" Cursor="Arrow" IsSynchronizedWithCurrentItem="False" BorderThickness="1" ClipToBounds="True" SnapsToDevicePixels="True" Grid.Row="1" Grid.RowSpan="2" Grid.Column="1">
<ListBox.ItemBindingGroup>
<BindingGroup/>
</ListBox.ItemBindingGroup>
<ListBox.Effect>
<hc:BrightnessEffect/>
</ListBox.Effect>
</ListBox>
I would recomend using a "data binding" in a ViewModel to make the code more readable.
You create a class (e.g. MainViewModel) and in there you create an ObservableCollection where you add or remove items from.
In the View (xaml file) you then add this ViewModel as a Source and use a Binding to add the items of the collection to your ListView.
Here is an example
Let me know if you can't get it to work.

How to add an Image and a Textblock into a WPF ContentControl

I have a ContentControl in WPF,which has an image in it
ContentControl myContentControl = new ContentControl();
myContentControl.Content = image;
How do I to add a textblock next to the image inside the ContentControl?
Thank you.
You need to change the property ContentTemplate of the contentControl, as to ContentTemplate, here is some explanation:
Gets or sets the data template used to display the content of the ContentControl.
Also you need create a class to represent your data, like this:
public class ImageInfo
{
public string Caption { get; set; }
public ImageSource Image { get; set; }
}
It is better to create ContentControl in XAML, like this:
<ContentControl x:Name="cc">
<ContentControl.ContentTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Image}" />
<TextBlock Text="{Binding Caption}" />
</StackPanel>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
Then, assign the data to the ContentControl:
cc.Content = new ImageInfo() { Caption = "Hello", Image = new BitmapImage(new System.Uri("/Assets/User.jpg", UriKind.Relative)) };
What you are doing looks like you are not familiar with MVVM:
Please check here
Easy Solution
But if you want the ugly solution and create UIElements in your code behind - go like this:
public static ContentControl CreateControl(string title, Uri path)
{
//Create your image
BitmapImage bitmapImage = new BitmapImage(path);
Image image = new Image()
{
Source = bitmapImage
};
//Create your Text
TextBlock textB = new TextBlock()
{
Text = title
};
//Put them together
StackPanel content = new StackPanel();
content.Children.Add(image);
content.Children.Add(textB);
//Add this to the content control
return new ContentControl()
{
Content = content
};
}

Image NOT displaying in Windows Phone 8

I am facing an issue while displaying an image from ApplicationData.Current.LocalFolder.
I am able to save an image and store it in LocalFolder, but displaying it in a Image control or LongListSelector, the image does not show up.
Here is the code:
private async void StoreToFile(string imageFileName)
{
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(imageFileName, CreationCollisionOption.GenerateUniqueName);
using (Stream current = await file.OpenStreamForWriteAsync())
{
await photoStream.CopyToAsync(current);
}
}
Here is the code to bind:
var folder = ApplicationData.Current.LocalFolder;
var images = await folder.GetFilesAsync();
Recent.ItemsSource = images.ToList();
XAML Code:
<phone:PivotItem Name="pivot1" Header="item2" Background="White">
<phone:LongListSelector x:Name="Recent" Margin="0,0,0,72" ItemsSource="{Binding lst}" >
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path}" Width="60"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</phone:PivotItem>
I am able to bind the path to a TextBlock and able to see the exact path like:
C:\Data\Users\DefApps\AppData{GUID}\Local\bucket.png
But if I bind to an image source, images are not displaying.
Can anyone see what I'm doing wrong?
You need to use the msappx uri scheme:
new Uri("ms-appx:///myimage.jpg");
As ToniPetrina has said in comment - you can't bind to Path, your property should return BitmapImage. There are two approaches that come to my mind:
provide a special getter of your property that will return BitmapImage (some code below)
provide a Converter when binding to IsolatedStorage image - here is very nice example
The sample code for the first solution can look like this:
In Xaml:
<ListBox Name="myList" Grid.Row="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding GetImgSource}" Width="60"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In code behind:
public class Images : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string imgSource = "";
public string SetImgSource // setter - string
{
set
{
imgSource = value;
RaiseProperty("GetImgSource");
}
}
public BitmapImage GetImgSource // getter - BitmapImage
{
get
{
if (String.IsNullOrEmpty(imgSource)) return null;
BitmapImage temp = new BitmapImage();
using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream file = ISF.OpenFile(imgSource, FileMode.Open, FileAccess.Read))
temp.SetSource(file);
return temp;
}
}
public void RaiseProperty(string property = null)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
ObservableCollection<Images> myImg = new ObservableCollection<Images>();
myList.ItemsSource = myImg; // somewhere

Get filepath of image on windows phone

I am developing a Windows Phone 8 application and have some pictures already in it which are populated into a listbox like this
<ListBox x:Name="Control" ItemsSource="{Binding Pictures}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="WhiteSmoke" Margin="10">
<Image Source="{Binding Source}" Margin="10"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The ViewModel is simple at the momment
public class MainPageViewModel : NotificationObject
{
private ObservableCollection<Picture> _pictures;
public MainPageViewModel()
{
Pictures = new ObservableCollection<Picture>
{
new Picture
{
Source = new BitmapImage(new Uri("../Images/Pictures/1.jpg", UriKind.Relative))
}
//Add more images here
};
}
public ObservableCollection<Picture> Pictures
{
get { return _pictures; }
set
{
_pictures = value;
RaisePropertyChanged(() => Pictures);
}
}
}
I now want that by tapping on an image the user gets options for sharing
void ShowShareMediaTask(object sender, GestureEventArgs e)
{
ShareMediaTask shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = //something needs to go here
shareMediaTask.Show();
}
Any ideas how I can get the physical (full) path of this image?
It looks like you are referencing images stored in the application folder (in the project) so the ShareMediaTask can't access it.
The ShareMediaTask requires the photo to be in the Media Library.
What you need to do is save the photo the the Media Library and then call the ShareMediaTask with the path of the saved image (don't forget to add the using Microsoft.Xna.Framework.Media.PhoneExtensions; to have access to the GetPath() extension method).
var picture = mediaLibrary.SavePicture(fileName, stream);
shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = picture.GetPath(); // requires using Microsoft.Xna.Framework.Media.PhoneExtensions;
shareMediaTask.Show();
yes... you can generate tap event of list box follow below code
private void Control_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
ObservableCollection<Picture> pictureobj=new ObservableCollection<Picture>();
ListBox lst = (ListBox)sender;
int i = lst.SelectedIndex;
if (lst.SelectedValue == null)
{
}
else
{
Pictures obj = (Pictures)lst.SelectedValue;
ShareMediaTask shareMediaTask = new ShareMediaTask();
shareMediaTask.FilePath = obj.yoursetterimagepath
shareMediaTask.Show();
}
}
hope it will help you

Bind image to datagrid using resources

I am trying to retrieve the image from resource file and tryin to bind it to the datagrid of my WPF application.
The datagrid is somewhat like this:
<DataGridTemplateColumn Header="Image" Width="45">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Icon}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
And Image is a property of type image of my MVVm class like this:
public Image Icon
{
get { return _licenseImage; }
set { _licenseImage = value;
PropertChanged("Icon");}
}
And in the code behind Im tryin to do something like this to get image from resource file and tryin to bind it to datagrid column.
ResourceManager resourceManager =
new ResourceManager("Resources.Images", Assembly.GetExecutingAssembly());
BitMap bitmap = resourceManager.GetObject("okimage") as BitMap;
Image image = bitmap;
return image;
I can see that image is populated but it is not displaying in the grid.
You should bind to an ImageSource instead of Image.
we use this helper class:
public static class ImageSourceHelper
{
public static ImageSource GetResourceImage(string resourcePath)
{
return GetResourceImage(Assembly.GetCallingAssembly(), resourcePath);
}
public static ImageSource GetResourceImage(Assembly resourceAssembly, string resourcePath)
{
if (string.IsNullOrEmpty(resourcePath)) return null;
var assembly = resourceAssembly.GetName().Name;
const string uriFormat = "pack://application:,,,/{0};component/{1}";
if (!UriParser.IsKnownScheme("pack")) new System.Windows.Application();
var uri = new Uri(string.Format(uriFormat, assembly, resourcePath), UriKind.RelativeOrAbsolute);
return BitmapFrame.Create(uri);
}
public static ImageSource ConvertFromGdiBitmap(Bitmap bitmap)
{
return Common.SystemAbstraction.Media.ImageConverter.ConvertToBitmapSource(bitmap);
}
public static Bitmap ConvertToGdiBitmap(ImageSource imageSource)
{
return Common.SystemAbstraction.Media.ImageConverter.ConvertToBitmap(imageSource as BitmapSource);
}
}
It creates an ImageSource from Bitmap or resource images.
Usage is
img.Source = ImageSourceHelper("Path/To/Your/Image.png");
or
var resourceAssembly = // get resource assembly...
img.Source = ImageSourceHelper(resourceAssembly, "Path/To/Your/Image.png");
if the image is contained in an other assembly than the currently calling assembly.
The path of your image is the path starting at the project file root of your assembly.
Say you have an folder images your path will be "images/somepicture.png".
I think the problem is that you are binding to the wrong property. Try this:
<Image Source="{Binding Path=Icon}" />

Categories

Resources