C# WPF display images like a grid - c#

Im a total C#/programming beginner.
I try to display alot of pictures like an album or grid like.
It looks like this so far:
http://i.imgur.com/LC7lhXi.jpg
But there are empty places and when I scroll down it looks even worse: http://i.imgur.com/QuFOgr1.png
I created a UniformGrid inside a ScrollViewer. That was the easiest way for me to get what I want. Maybe not the best solution. If I add more pictures the images are getting smaller. I think thats cause of the uniform grid.
Here are two code example how I did that.
js.movie1 is an object which contains a few members. js.movie1[0].poster is the file name of the first picture (there are 275 pictures).
This object is created by the JSON.NET framework. It just reads a JSON file set some variables and I put the object in a list.
for example js.movie1[0].poster is the file name of the poster as a picture, js.movie1[0].title is the title of the movie and so on.
private void btnShow_Click(object sender, RoutedEventArgs e)
{
uGrid.Children.Clear();
string strWebAdress = #"https://image.tmdb.org/t/p/original/";
for (int i = 0; i < js.movie1.Count; i++)
{
Image img = new Image();
BitmapImage bimg = new BitmapImage(new Uri(strWebAdress + js.movie1[i].poster));
//bimg.sou
img.BeginInit();
img.Source = bimg;
img.EndInit();
uGrid.Children.Add(img);
}
Or I did this:
private void btnShow_Click(object sender, RoutedEventArgs e)
{
uGrid.Children.Clear();
string strWebAdress = #"https://image.tmdb.org/t/p/original/";
List<string> listImage = Directory.GetFiles(strPath, "*jpg").Select(System.IO.Path.GetFileName).ToList();
List<Image> imgList = new List<Image>();
for (int i = 0; i < js.movie1.Count; i++)
{
Image Controlimage = new Image
{
Source = new BitmapImage(new Uri(strCoverUrl + js.movie1[i].poster)),
};
uGrid.Children.Add(Controlimage);
}
My problem is that there are empty spaces between some pictures, I cant resize them like I want. And I want to scroll while the program is loading the pictures.
The program needs 1,5 GB of Ram and alot of CPU power so I need a betetr solution for this.
With Foreach I can scroll but I created a array for that. I dont know how to count in foreach with a object. Atleast not in the way my object is used.
There have to be a way to load and display pictures from an URL which doesnt block the UI and needs so much power.
Like I said Im a bloody beginner ;)
Greetings Fabian :)

Related

How to property remove (or keep) the background and contents when exporting PDF to PNG using Magic.NET-Q16-AnyCPU

https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf
First time trying the Magic.NET-Q16-AnyCPU and I encounter an issue that I think I just do know the correct method to use I hope someone could lead me to get this corrected. I have a pdf with some existing texts and tables, plus a redline text added by using a pdf editing software.
Attached picture #1: depends on which software I use to view the png, some software shows black background. I like to have the background can show white or show as transparent (which is preferred) for all software. With page containing the red line text, it shows the red line one correctly but the other contents.
Attached picture #2: If I use settings.UseMonochrome = true; then this is no longer an issue but the resulting image I get is not what I prefer. I may sound stupid but with settings.UseMonochrome = false; my eyes feel better, especially when there are some graphics and tables.
Can I set settings. UseMonochrome = false; and still get all the contents shown correctly? And can I ensure the PNG background is either removed or set as White? Already try the image.BackgroundColor = MagickColors.White; but this does not impact the result.
private void button1_Click(object sender, EventArgs e)
{
var settings = new MagickReadSettings();
settings.Density = new Density(100, 100);
//Do not want to use this
//settings.UseMonochrome = true;
var filename = #"C:\Users\USER1\Desktop\dummy.pdf";
using (var images = new MagickImageCollection())
{
if(System.IO.File.Exists(filename))
{
images.Read(filename, settings);
var page = 1;
foreach (var image in images)
{
image.Write("C:\\Users\\USER1\\Desktop\\dummy.PNG");
page++;
}
}
}
}

How to fix ListView.LargeImageList showing images twice

I am working on a piece of software, which compares memes and helps users organize memes on their computer. As a part of this I am using Windows.Forms to build a UI. This UI lets the user add folders to be checked for images, which can be compared to a set of known meme templates.
My issue arises when I try to show the user the found images. To do this I am using a ListView and the property LargeImageList to contain a tuple of the image and the name of the image file.
Here is the piece of code in question:
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
var ic = new ImageCollection();
var fbd = new FolderBrowserDialog();
fbd.Description = "Select meme folder or image.";
if (fbd.ShowDialog() == DialogResult.OK)
{
string[] files = Directory.GetFiles(fbd.SelectedPath);
foreach (var file in files)
{
if (!ic.CheckIfImage(file)) continue;
imageList1.Images.Add(Image.FromFile(file));
}
foreach (var file in files)
{
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
}
}
}
This is an example of what the user sees when they first load in a folder. When the user tries to load in another folder this happens. It shows the images from the first folder, with the names of the image files from the second folder.
Does anyone know a fix for this issue? I have tried a variety of options in order to get around the issue. All from trying to clear the ImageList used to contain the images, to trying my hand at controlling when the ListView updates. None of this has worked. I have also tried googling the issue, but with no luck of finding a fix.
Thank you in advance.
If you want to show the content of a single folder at the time, then dispose of the objects in your ImageList.
If you instead want to show the content of more than one folder, you need to specify the new index of the image added. You're instead adding a new Item in the ListView using the same index reference:
int i = 0;
//(...)
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
The indexer (i) always starts from 0, thus the ListView Item will use the images in your Imagelist starting from the Image at Index[0] each time. The new images won't ever be shown.
You can use the ImageList.Images.Count value, representing the number of Images already added to the ImageList, as base and increment the indexer starting from this value:
private void button1_Click(object sender, EventArgs e)
{
int i = imageList1.Images.Count;
var ic = new ImageCollection();
var fbd = new FolderBrowserDialog();
fbd.Description = "Select meme folder or image.";
if (fbd.ShowDialog() == DialogResult.OK)
{
foreach (var file in Directory.GetFiles(fbd.SelectedPath))
{
if (!ic.CheckIfImage(file)) continue;
imageList1.Images.Add(new Bitmap(file, true));
listView1.Items.Add($"{Path.GetFileNameWithoutExtension(file)}", i++);
}
}
}
If you allow to remove an Image from the ListView, you should also remove it from the ImageList: this implies that you need to re-index all the ListView Items starting from the Item that follows the one removed.
Remember to dispose of the Images you remove from the ImageList.

Populating winform ListView from Calling External Class, not adding image and text

I am trying to add a new image list with text describing each image below each image. I have set the listview to large icons and tried many other attempts to get preview images back into the first form.
I have been able to either
1. get very small images into the list view
2. get just the text into the listview
3. get the very tiny images again with text first then the images, not together.
I have tried all the overloaded methods and I am still at a loss as to why i can't even get a Properties.resources.image in as an image placeholder. except as a tiny image. And yes I have set the listview large icon mode and tried the imageSize properties, nothing works. Also some attempts usually with a technique that appears like it is following an explanation on here fails to show anything in the listview on the frstForm.
Any hints would be appreciated.
public ImageList imageList_c = new ImageList();
private Family_Loader_ExtEventDialog _frstForm;
foreach (KeyValuePair<string, Bitmap> kvp in element_Dict(_doc_new, BuiltInCategory.OST_Walls))
{
//imageList_c.ImageSize = new Size(120, 120);
//imageList_c.Images.Add(kvp.Key, Properties.Resources.folder);
_frstForm.listView_Family.Items.Add(kvp.Key);
}
//_frstForm.listView_Family.LargeImageList = imageList_c;
imageList_c.Images.Add(kvp.Key, kvp.Value);
_frstForm.listView_Family.View = System.Windows.Forms.View.LargeIcon;
_frstForm.listView_Family.LargeImageList = imageList_c;
for (int i = 0; i < imageList_c.Images.Count; i++)
{
ListViewItem item = new ListViewItem();
item.ImageIndex = i;
item.Text = imageList_c.Images.Keys[i];
_frstForm.listView_Family.Items.Add(item);
}

Winforms Listbox or Listview image and text

I'm not very experienced on c#. I'm working with winforms and I'm looking for a way to create something like a list of elements with this template , something like the autocompletion list of visual studio.
Is it possible to do? Shall I use listbox or listview?
EDIT
Sorry my question wasn't clear I don't want to create an autocomplete but what i want to create is something like this a list of things with an icon next to the text of that thing.
As I understand from your question, you can create custom UserControl or create a Form and put ListBox in it. If you use From be sure that you change border style layout, just set it to none. After creation for use it you should create form and show it where you want like this:
FrmAutoComplete x = new FrmAutoComplete();
x.Show();
you can put this form in ToolTipItem and show it.
Good luck.
THis is a quick and dirty example of using images in your Listview control. Since I don;t have a lot of information about what you plan to do, I tried to keep is simple.
In short, you need to load some images into one of the ImageLists (Large or Small) built into the Listview control and assign them keys so that you can assign them to specific list items as you add them.
The trick to this is determining which image to use for a specific list item (assuming there are different images assigned to different list items depending on some differentiating factor. For this example, I used an arbitrary assignment of "cars" or "trucks," and simply decided that the first five items in the list would be cars, and the last five would be trucks. I then assigned each image appropriately, using the image key as I added each listview item. You can do this for more complex scenarios, and when using the image key, it does not matter what order the items are added.
For this use case, you will want to create or use images with dimensions of 16 x 16 pixels. I went ahead and added two images to my project resource file, then simply accessed them using the project Properties.Resources name space. There are other ways to do this as well, but this is the most convenient for me.
Hope that helps.
public partial class Form1 : Form
{
static string CAR_IMAGE_KEY = "Car";
static string TRUCK_IMAGE_KEY = "Truck";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.SetupListview();
this.LoadListView();
}
private void SetupListview()
{
var imgList = new ImageList();
imgList.Images.Add("Car", Properties.Resources.jpgCarImage);
imgList.Images.Add("Truck", Properties.Resources.jpgTruckImage);
var lv = this.listView1;
lv.View = View.List;
lv.SmallImageList = imgList;
}
private void LoadListView()
{
for(int i = 1; i <= 10; i++)
{
string currentImageKey = CAR_IMAGE_KEY;
if(i > 5) currentImageKey = TRUCK_IMAGE_KEY;
var item = this.listView1.Items.Add("Item" + i.ToString(), currentImageKey);
}
}

Adding a picture from a resource to a picture box

I got this issue with displaying a image that i allready have added as a resource. I am guessing i am missing something vital but i cant find what it is. I am hoping that someone has a better idea of what i am doing wrong atm.
I have added an .bmp image into the solutiontree and changed the build action properties of that image to Embedded resource but i cant figure out how to call that image from the pipe?
as the user clicks a button the image should be sent to the imagebox, the code i have written so far looks like this:
this is ofs only the button_click code:
private void button1_Click(object sender, EventArgs e)
{
//Show image in the picturebox of selected cake
Image image = Image.FromFile(fruitcake.jpg);
pictbox.Image = image;
pictbox.Height = 163;
pictbox.Width = 223;
choice = 1;
lblCookiesPerGram.Text = string.Empty;
}
Anyone has an idea of what i am doing wrong or can i do this in another war? mind thou its 4 buttons the user clicks and there is a image for each one ;)
//Regards
If you go to your Solution - Properties window and select the Resources tab and add the image through this manager, then the images can be directly referenced like this:
Image image = Properties.Resources.fruitcake;
To retrieve an image from a resource, you can do something like:
using (Stream imgStream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(
"MyNamespace.resources.fruitcake.jpg"))
{
var image = new Bitmap(imgStream);
pictBox.Image = image;
pictBox.Height = image.Height;
pictBox.Width = image.Width;
}

Categories