Actually I am in trouble. My project is to create a desktop with shortcuts. The desktop is ready, it is a picturebox as background. And now the shortcuts.
Through a dialog, I will create a shortcut on the picturebox (desktop). Example:
Here is my desktop:
https://pasteboard.co/IHSdXvX.png
Here is my dialog:
https://pasteboard.co/IHSefrz.png
First textbox is the path to the file. Second textbox is the name of the shortcut.
And here is the result:
https://pasteboard.co/IHSeM7Y.png
In the upper left corner is a new green shortcut. It is a picturebox, which was created by this code:
Icon ico = Icon.ExtractAssociatedIcon(textBox1.Text);
var picture = new PictureBox
{
Name = textBox2.Text,
Size = new Size(48, 46),
Location = new Point(100, 100),
Image = ico.ToBitmap(),
SizeMode = PictureBoxSizeMode.Zoom,
};
Form1Singleton.FormVerweis.pictureBox1.Controls.Add(picture);
So, my question is:
How can I save the new created picturebox (the green icon upper left corner) and load it back to the same position, and the same click-Event to start the .exe behind it (exe path in textbox 1 in the dialog before) when the application starts. Information about the picturebox to save: Location, Icon, .exe Path.
Thanks for your help and I am really happy about code-examples.
Joshua
You will need to create a class that stores all the information you need to create an icon:
[Serializable]
public class IconDefinition
{
public string Name { get; set; }
public string Path { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
Then you have some method that actually creates your icon based on these values:
void createIcon(IconDefinition iconDefinition)
{
PictureBox pictureBox = new PictureBox()
{
Name = iconDefinition.Name,
Size = new Size(iconDefinition.Width, iconDefinition.Height),
Location = new Point(iconDefinition.X, iconDefinition.Y),
Image = Icon.ExtractAssociatedIcon(iconDefinition.Path).ToBitmap(),
SizeMode = PictureBoxSizeMode.Zoom
};
pictureBox.Click += myClickHandler;
Form1Singleton.FormVerweis.pictureBox1.Controls.Add(pictureBox);
}
Next you have your methods to serialize and deserialize these. Since you probably want to store all your icons in the same file for persistence you would use a List for serialization.
static void saveIcons(List<IconDefinition> icons)
{
using (Stream stream = new FileStream(#".\icons.bin", FileMode.Create, FileAccess.Read))
new BinaryFormatter().Serialize(stream, icons);
}
static List<IconDefinition> loadIcons()
{
using (Stream stream = new FileStream(#".\icons.bin", FileMode.Open, FileAccess.Read))
return (List<IconDefinition>)new BinaryFormatter().Deserialize(stream);
}
These will provide you functionality to write a List<IconDefinition> to a file, or restore it from a file.
Now you will have to have a place somewhere to put all your icons:
List<IconDefinition> allIcons = new List<IconDefinition>();
When manually creating the icon (as you do already):
IconDefinition iconDefinition = new IconDefinition()
{
Path = textBox1.Text,
Name = textBox2.Text,
X = 100,
Y = 100,
Width = 48,
Height = 46
};
allIcons.Add(iconDefinition);
createIcon(iconDefinition);
When you want to save all your icons:
saveIcons(allIcons);
And when your application starts to restore them:
// When application starts you can load the icons
allIcons = loadIcons();
// then restore them all
foreach (IconDefinition definition in allIcons)
createIcon(definition);
Hope that helps.
Related
In my UWP app I'm using two images to test the HintOverLay property with a background image. But the tile does not show the image or or the overlay of the image. I'm using the Maps.xml example of official Notifications Visualizer. Their example works fine on my system. But the following code does not:
Question: What I may be missing and how can we make it work. I've verified that the untitled3.png and untitled4.png exist in the Assets/Apps/ folder. I'm using VS2019 - ver16.6.2 on Windows10 Pro -ver1903?
UPDATE:
Screenshot of Images junk1.png and junk2.png [size: 100x100 pixels]
Screenshot of Solution Explorer:
Code:
.....
.....
TileContent content = new TileContent()
{
Visual = new TileVisual()
{
TileMedium = new TileBinding()
{
Content = new TileBindingContentAdaptive()
{
BackgroundImage = new TileBackgroundImage()
{
Source = "Assets/Apps/junk1.png"
},
PeekImage = new TilePeekImage()
{
Source = "Assets/Apps/junk2.jpg",
HintOverlay = 20
}
}
},
TileWide = new TileBinding()
{
Content = new TileBindingContentAdaptive()
{
BackgroundImage = new TileBackgroundImage()
{
Source = "Assets/Apps/junk1.png"
},
PeekImage = new TilePeekImage()
{
Source = "Assets/Apps/junk2.png",
HintOverlay = 20
}
}
}
}
};
// Create the tile notification
TileNotification notification = new TileNotification(content.GetXml());
TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true);
// Send the notification to the primary tile
TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);
I have a report where there is a static image, but I need to load the image dynamically.
Already checked this, this, this and this
All I tried without success. I need some sample code.
Any suggestion?
To load images dynamically I created a new class/model called ImageModel.
public class ImageModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Byte[] ImageBytes { get; set; }
}
This class has a field called Image, it will load the image.
The next step is add ImageBytes field to the report.
Through Crystal Report interface, using the Field Explorer, it was to create a new connection. In this new connection I used my ImageModel class as a model.
By adding the ImageBytes field, I noticed that Crystal Reports added a type crBlobFieldObject object.
To load the image was necessary to make the following code:
public Byte[] GetImageBytes(string image_name)
{
Byte[] bytes = null;
if (!string.IsNullOrEmpty(image_name))
{
string app_path = ((System.Web.HttpRequestWrapper)this.Request)
.PhysicalApplicationPath;
app_path += "Content\\images\\";
string full_path = app_path + image_name;
//
if (System.IO.File.Exists(full_path))
{
FileStream fs = new FileStream(full_path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
bytes = br.ReadBytes(Convert.ToInt32(br.BaseStream.Length));
}
}
return bytes;
}
The main code looks like this:
public JsonResult GenerateCrystalReportImage()
{
List<ImageModel> list_image = new List<ImageModel>();
//
ImageModel imageone = new ImageModel();
imageone.Id = 1;
imageone.Name = "Image name one";
imageone.Description = "This is a image description one";
imageone.Image = GetImageBytes("imageone.png");
list_image.Add(imageone);
//
ImageModel imagetwo = new ImageModel();
imagetwo.Id = 2;
imagetwo.Name = "Image name two";
imagetwo.Description = "This is a image description two";
imagetwo.Image = GetImageBytes("imagetwo.png");
list_image.Add(imagetwo);
//
ReportDocument rp = new ReportDocument();
rp.Load(System.Web.HttpContext.Current.Server.MapPath("~/Reports/") + "Test.rpt");
rp.SetDataSource(list_image);
rp.ExportToHttpResponse(ExportFormatType.PortableDocFormat,
System.Web.HttpContext.Current.Response,
false,
"image_list_" + DateTime.Now);
rp.Close();
return Json(new
{
data = "ok",
results = 1,
success = true,
errors = String.Empty
}, JsonRequestBehavior.AllowGet);
}
I have a icon which has a few different sizes (16px, 32px, 64px). I am calling ToBitmap() on it, but it is always returning the 32px image. How do I retrieve the 64px one?
Does this help?
Icon sizedIcon = new Icon(Resources.ResourceIcon, new Size(64,64));
For anyone else stumbling upon the same problem, I've found a nice little solution.
Image img = new Icon(Properties.Resources.myIcon, width, height).ToBitmap()
This is a fairly painful limitation in the ResourceManager class. Its GetObject() method doesn't provide a way to pass extra arguments that would allow selecting the returned icon by size. A workaround is to add the icon to the project instead. Use Project + Add Existing Item, select your .ico file. Select the added icon and change the Build Action property to "Embedded Resource".
You can now retrieve the desired icon with code like this:
public static Icon GetIconFromEmbeddedResource(string name, Size size) {
var asm = System.Reflection.Assembly.GetExecutingAssembly();
var rnames = asm.GetManifestResourceNames();
var tofind = "." + name + ".ICO";
foreach (string rname in rnames) {
if (rname.EndsWith(tofind, StringComparison.CurrentCultureIgnoreCase)) {
using (var stream = asm.GetManifestResourceStream(rname)) {
return new Icon(stream, size);
}
}
}
throw new ArgumentException("Icon not found");
}
Sample usage:
var icon1 = GetIconFromEmbeddedResource("ARW04LT", new Size(16, 16));
var icon2 = GetIconFromEmbeddedResource("ARW04LT", new Size(32, 32));
Beware one possible failure mode: this code assumes that the icon was added to the same assembly that contains the method.
The following sets the icon size for all the buttons in the toolbar.
It relies on the resource name being stored in the button tag.
public void SetButtons(object toolstrip, int IconWidth, int IconHeight)
{
var ts = (ToolStrip) toolstrip;
var size = new System.Drawing.Size();
size.Height = IconSize;
size.Width = IconSize;
foreach (ToolStripButton tsBtn in ts.Items)
{
tsBtn.ImageScaling = ToolStripItemImageScaling.None;
var resourcename = (String) tsBtn.Tag;
if (resourcename != null)
{
var myIcon = (Icon) Properties.Resources.ResourceManager.GetObject(resourcename);
var newIcon = new Icon(myIcon, IconWidth, IconHeight);
tsBtn.Image = newIcon.ToBitmap();
}
}
}
The size is determined when you first create the Icon instance, so you need to specify which size you want to use when you create it, using one of the Icon constructors that take a Size parameter.
internal static class IconHelper {
public static Icon GetSize(this Icon icon, int width, int height) {
return icon.GetSize(new Size(width, height));
}
public static Icon GetSize(this Icon icon, Size size) {
using(var mem = new MemoryStream()) {
icon.Save(mem);
mem.Position = 0;
return new Icon(mem, size);
}
}
}
There is no built-in method in the .Net framework that does this.
Instead, you can use this library.
I have a icon which has a few different sizes (16px, 32px, 64px). I am calling ToBitmap() on it, but it is always returning the 32px image. How do I retrieve the 64px one?
Does this help?
Icon sizedIcon = new Icon(Resources.ResourceIcon, new Size(64,64));
For anyone else stumbling upon the same problem, I've found a nice little solution.
Image img = new Icon(Properties.Resources.myIcon, width, height).ToBitmap()
This is a fairly painful limitation in the ResourceManager class. Its GetObject() method doesn't provide a way to pass extra arguments that would allow selecting the returned icon by size. A workaround is to add the icon to the project instead. Use Project + Add Existing Item, select your .ico file. Select the added icon and change the Build Action property to "Embedded Resource".
You can now retrieve the desired icon with code like this:
public static Icon GetIconFromEmbeddedResource(string name, Size size) {
var asm = System.Reflection.Assembly.GetExecutingAssembly();
var rnames = asm.GetManifestResourceNames();
var tofind = "." + name + ".ICO";
foreach (string rname in rnames) {
if (rname.EndsWith(tofind, StringComparison.CurrentCultureIgnoreCase)) {
using (var stream = asm.GetManifestResourceStream(rname)) {
return new Icon(stream, size);
}
}
}
throw new ArgumentException("Icon not found");
}
Sample usage:
var icon1 = GetIconFromEmbeddedResource("ARW04LT", new Size(16, 16));
var icon2 = GetIconFromEmbeddedResource("ARW04LT", new Size(32, 32));
Beware one possible failure mode: this code assumes that the icon was added to the same assembly that contains the method.
The following sets the icon size for all the buttons in the toolbar.
It relies on the resource name being stored in the button tag.
public void SetButtons(object toolstrip, int IconWidth, int IconHeight)
{
var ts = (ToolStrip) toolstrip;
var size = new System.Drawing.Size();
size.Height = IconSize;
size.Width = IconSize;
foreach (ToolStripButton tsBtn in ts.Items)
{
tsBtn.ImageScaling = ToolStripItemImageScaling.None;
var resourcename = (String) tsBtn.Tag;
if (resourcename != null)
{
var myIcon = (Icon) Properties.Resources.ResourceManager.GetObject(resourcename);
var newIcon = new Icon(myIcon, IconWidth, IconHeight);
tsBtn.Image = newIcon.ToBitmap();
}
}
}
The size is determined when you first create the Icon instance, so you need to specify which size you want to use when you create it, using one of the Icon constructors that take a Size parameter.
internal static class IconHelper {
public static Icon GetSize(this Icon icon, int width, int height) {
return icon.GetSize(new Size(width, height));
}
public static Icon GetSize(this Icon icon, Size size) {
using(var mem = new MemoryStream()) {
icon.Save(mem);
mem.Position = 0;
return new Icon(mem, size);
}
}
}
There is no built-in method in the .Net framework that does this.
Instead, you can use this library.
I'm using a class I've derived from DocumentPaginator (see below) to print simple (text only) reports from a WPF application. I've got it so that everything prints correctly, But how do I get it to do a print preview before printing? I have a feeling I need to use a DocumentViewer but I can't figure out how.
Here's my Paginator Class:
public class RowPaginator : DocumentPaginator
{
private int rows;
private Size pageSize;
private int rowsPerPage;
public RowPaginator(int rows)
{
this.rows = rows;
}
public override DocumentPage GetPage(int pageNumber)
{
int currentRow = rowsPerPage * pageNumber;
int rowsToPrint = Math.Min(rowsPerPage, rows - (rowsPerPage * pageNumber - 1));
var page = new PageElementRenderer(pageNumber + 1, PageCount, currentRow, rowsToPrint)
{
Width = PageSize.Width,
Height = PageSize.Height
};
page.Measure(PageSize);
page.Arrange(new Rect(new Point(0, 0), PageSize));
return new DocumentPage(page);
}
public override bool IsPageCountValid { get { return true; } }
public override int PageCount { get { return (int)Math.Ceiling(this.rows / (double)this.rowsPerPage); } }
public override Size PageSize
{
get { return this.pageSize; }
set
{
this.pageSize = value;
this.rowsPerPage = PageElementRenderer.RowsPerPage(this.pageSize.Height);
if (rowsPerPage <= 0)
throw new InvalidOperationException("Page can't fit any rows!");
}
}
public override IDocumentPaginatorSource Source { get { return null; } }
}
The PageElementRenderer is just a simple UserControl that displays the data (at the moment just a list of rows).
Here's how I use my Row Paginator
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() == true)
{
var paginator = new RowPaginator(rowsToPrint) { PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight) };
dialog.PrintDocument(paginator, "Rows Document");
}
Sorry for the code dump, but I didn't want to miss something relevant.
So I got it working after reading Pro WPF in C# 2008 (Page 726).
Basically the DocumentViewer class needs an XPS file to present a print preview of it. So I do the following:
PrintDialog dialog = new PrintDialog();
var paginator = new RowPaginator(rowsToPrint) { PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight) };
string tempFileName = System.IO.Path.GetTempFileName();
//GetTempFileName creates a file, the XpsDocument throws an exception if the file already
//exists, so delete it. Possible race condition if someone else calls GetTempFileName
File.Delete(tempFileName);
using (XpsDocument xpsDocument = new XpsDocument(tempFileName, FileAccess.ReadWrite))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
writer.Write(paginator);
PrintPreview previewWindow = new PrintPreview
{
Owner = this,
Document = xpsDocument.GetFixedDocumentSequence()
};
previewWindow.ShowDialog();
}
I'm creating the print dialog to get the default page size. There's probably a better way to do this.
XpsDocument is in ReachFramework.dll (Namespace System.Windows.Xps.Packaging);
Here's the PrintPreview Window.
<Window x:Class="WPFPrintTest.PrintPreview"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="previewWindow"
Title="PrintPreview" Height="800" Width="800">
<Grid>
<DocumentViewer Name="viewer"
Document="{Binding ElementName=previewWindow, Path=Document}" />
</Grid>
</Window>
The code behind just has a Document property like so:
public IDocumentPaginatorSource Document
{
get { return viewer.Document; }
set { viewer.Document = value; }
}
The following code uses a MemoryStream to do a print preview.
MemoryStream stream = new MemoryStream();
Package package = Package.Open(stream, FileMode.Create, FileAccess.ReadWrite);
var uri = new Uri(#"memorystream://myXps.xps");
PackageStore.AddPackage(uri, package);
var xpsDoc = new XpsDocument(package);
xpsDoc.Uri = uri;
XpsDocument.CreateXpsDocumentWriter(xpsDoc).Write(paginator);
documentViewer.Document = xpsDoc.GetFixedDocumentSequence();
Remember to use close() and remove package from PackageStore when the print preview is closed.
WPF doesn't come with any built-in Print Preview functionality, if you want to do a print preview, you're going to have to construct it yourself. Fortunately, it's shouldn't be that difficult.
You've already got the pagination code, which creates your DocumentPage objects. These objects contain a Visual, which you can go ahead and display in your UI.
What you'll end up doing, is paginating your entire document, collecting all the DocumentPage objects, then displaying their visuals inside of a scrolling StackPanel or something similar. These are the same DocumentPage objects that you can then send to the printer.
XpsDocument doc = new XpsDocument("filename.xps", FileAccess.Read);
docViewer.Document = doc.GetFixedDocumentSequence();
doc.Close();
The WinForm code for print preview is:
PrintPreviewDialog PrintPreviewDialog = new PrintPreviewDialog();
PrintPreviewDialog.Document = PrintDocument;
PrintPreviewDialog.ShowDialog();
P.s.: The original poster has commented that this is the wrong answer for an WPF application.
I dont think there is a built in way of doing this
Here is how I got it working in NHaml
var documentViewHostDialog = new DocumentDialog();
documentViewHostDialog.LoadDocument(load);
documentViewHostDialog.ShowDialog();
Where "load" is either a FlowDocument or IDocumentPaginatorSource
and here is the DocumentDialog
http://code.google.com/p/nhaml/source/browse/trunk/src/NHaml.Xps/DocumentDialog.xaml
http://code.google.com/p/nhaml/source/browse/trunk/src/NHaml.Xps/DocumentDialog.xaml.cs
Hope it works for your case.