C# How to Display Image(resource) array in TabPage - c#

Goal: when the application starts I want to generate a button per each picture in my resources (6 for testing, 128 final build), in side of a TabPage.
Here is where i am at so far:
private void tabPage1_load(object sender, EventArgs e)
{
ResourceSet rs = new ResourceSet("");
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
}
this doesn't seem to do the trick, any suggestions would be greatly appreciated
Edit(addition): the issue is when the application starts I'm not seeing the images listed int "tabPage1".
also yes i do have 6 images added to my "Resource Folder" inside Visual Studios.
Just for future folks i wanted to add the finished working code:
// Button list start
// Credit to Jcl
ResourceSet rs = Properties.Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
int yposition = 0;
foreach (var bmp in CIcons)
{
Button button = new Button();
button.Location = new Point(0, yposition);
button.Size = new Size(125, 125);
button.Visible = true;
button.BackgroundImage = bmp;
tabPage1.Controls.Add(button);
yposition += 125;
}
//Button list end

If you want to generate a button, I'd say something like:
private void tabPage1_load(object sender, EventArgs e)
{
ResourceSet rs = new ResourceSet("");
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
// Vertical aligned: i'll let you figure out how to position them
int yposition = 0;
foreach(var bmp in CIcons)
{
var button = new Button();
button.Location = new Point(0, yposition);
button.Size = new Size(50, 20); // for example
button.Visible = true;
button.BackgroundImage = bmp;
tabPage1.Controls.Add(button);
yposition += 20; // height of button
}
}
Update
As noted in the comments (I thought it was example code, but seems it's not), you also need to specify where to get the ResourceSet from. In your case, change:
ResourceSet rs = new ResourceSet("");
for
ResourceSet rs = Properties.Resources.ResourceManager.GetResourceSet(
CultureInfo.CurrentUICulture, true, true);
Code legibility bonus
All this code:
IDictionaryEnumerator id = rs.GetEnumerator();
List<Bitmap> CIcons = new List<Bitmap>();
while (id.MoveNext())
{
if (id.Value is Bitmap)
CIcons.Add((Bitmap)id.Value);
}
Is equivalent to:
List<Bitmap> CIcons = new List<Bitmap>();
foreach(var bmp in rs.OfType<Bitmap>())
CIcons.Add(bmp);
And since you can create a list from an enumerable, you could simply do:
List<Bitmap> CIcons = new List<Bitmap>(rs.OfType<Bitmap>());
But also, since you are not using your bitmap list for anything else than creating the buttons, you could just not define it, and then your whole code becomes:
var rs = Properties.Resources.ResourceManager.GetResourceSet(
CultureInfo.CurrentUICulture, true, true);
int yposition = 0;
foreach (var bmp in rs.OfType<Bitmap>())
{
var button = new Button()
{
Location = new Point(0, yposition),
Size = new Size(125, 125),
Visible = true,
BackgroundImage = bmp,
};
tabPage1.Controls.Add(button);
yposition += 125;
}
This could be further optimized: if I was you, instead of positioning by calculating the pixel location of each component, I'd use a FlowLayoutPanel to arrange the buttons. Usage of the FlowLayoutPanel is way outside the scope of this question though, I'm just mentioning it just in case you want to investigate and google further

Related

DevExpress XtraReport replace XRPictureBox control on runtime

So in our Report we have an ImageBox in the Detail Band which we want to have a different image per page.
Seeing that changing it in the BeforePrint Event of the Detail Band doesn't work (since it's only called once per print of the Report) I followed the following approach so far (which doesn't work):
In the PrintOnPage Event of a label of the Page Header Band of the Report (in order to have it called per page and be able to use the PrintOnPageEventArgs in the new XRPictureBox - I need the PageIndex):
private void xrLabel10_PrintOnPage(object sender, PrintOnPageEventArgs e)
{
this.Detail.Controls.Remove(xrPictureBox1); //Existing PictureBox control
this.Detail.Controls.Add(PictureBox(e));
}
Which calls this:
private List<Bitmap> _imageList;
public XRPictureBox PictureBox(PrintOnPageEventArgs e)
{
XRPictureBox pictureBox = new XRPictureBox();
var articleService = DependencyResolver.Current.GetService<IArticleService>();
int width;
int height;
pictureBox.Name = "xrPictureBox_" + e.PageIndex;
pictureBox.BackColor = Color.Transparent;
pictureBox.Dpi = 254F;
pictureBox.LocationFloat = new DevExpress.Utils.PointFloat(108.4792F, 71.4375F);
pictureBox.Name = "xrPictureBox_" + e.PageIndex;
pictureBox.SizeF = new SizeF(950F, 1225F);
pictureBox.Sizing = ImageSizeMode.Squeeze;
pictureBox.StylePriority.UseBackColor = false;
if (ReportUnit == ReportUnit.HundredthsOfAnInch)
{
width = (int)(GraphicsUnitConverter.Convert(xrPictureBox1.Size.Width, GraphicsUnit.Inch, GraphicsUnit.Pixel) / 100);
height = (int)(GraphicsUnitConverter.Convert(xrPictureBox1.Size.Height, GraphicsUnit.Inch, GraphicsUnit.Pixel) / 100);
}
else
{
width = (int)(GraphicsUnitConverter.Convert(xrPictureBox1.Size.Width, GraphicsUnit.Millimeter, GraphicsUnit.Pixel) / 10);
height = (int)(GraphicsUnitConverter.Convert(xrPictureBox1.Size.Height, GraphicsUnit.Millimeter, GraphicsUnit.Pixel) / 10);
}
if (_imageList == null)
{
_imageList = articleService .GetListOfImages((int)articleId.Value, width, height, PageColor); //this gets a List<Bitmap>
}
if (_imageList[e.PageIndex] == null)
return null;
pictureBox.Image = _imageList[e.PageIndex];
return pictureBox;
}
So basically my idea was to replace the existing Control with a new XRPictureBox with the new image. But it just doesn't appear in the Report, even though while debugging I see the code being run and retrieving the correct images for the correct pages.
Edit: nempoBu4's answer is correct generally, but unfortunately I failed to clarify an additional issue which makes it not perfect for my situation:
The report also has a subreport right next to the PictureBox and this subreport can expand to more than one pages. We wanted the PictureBox to render a different image in each of these pages and they don't trigger the PrintOnPage event of the PictureBox. I will add an answer with the workaround we found as soon as I can :)
PictureBox
You can use the PrintOnPage event of your PictureBox itself.
Here is example:
var source = new List<Tuple<int, string>>();
for (int index = 0; index < 100; index++)
source.Add(new Tuple<int, string>(index, "Name" + index));
var pictureBox = new XRPictureBox();
pictureBox.PrintOnPage += (sender, e) =>
{
if (_imageList[e.PageIndex] == null)
return;
pictureBox.Image = _imageList[e.PageIndex];
};
var labelItem1 = new XRLabel();
labelItem1.DataBindings.Add("Text", null, "Item1");
labelItem1.LeftF = 100;
var labelItem2 = new XRLabel();
labelItem2.DataBindings.Add("Text", null, "Item2");
labelItem2.LeftF = 200;
var detail = new DetailBand();
detail.Controls.AddRange(new XRControl[] { pictureBox, labelItem1, labelItem2 });
var report = new XtraReport();
report.Bands.Add(detail);
report.DataSource = source;
report.ShowRibbonPreview();
The result of example:
Watermarks
If you want to have only one image per page then you can use watermarks.
Here is example:
var source = new List<Tuple<int, string>>();
for (int index = 0; index < 100; index++)
source.Add(new Tuple<int, string>(index, "Name" + index));
var labelItem1 = new XRLabel();
labelItem1.DataBindings.Add("Text", null, "Item1");
labelItem1.LeftF = 100;
var labelItem2 = new XRLabel();
labelItem2.DataBindings.Add("Text", null, "Item2");
labelItem2.LeftF = 200;
var detail = new DetailBand();
detail.Controls.AddRange(new XRControl[] { labelItem1, labelItem2 });
var report = new XtraReport();
report.Bands.Add(detail);
report.DataSource = source;
report.CreateDocument();
foreach (Page page in report.Pages)
if (_imageList[page.Index] != null)
{
var watermark = new Watermark();
watermark.Image = _imageList[page.Index];
page.AssignWatermark(watermark);
}
report.ShowRibbonPreview();
Here is result:

How to add multiple makers on Gmap in c#

I have a text file with a list of GPS coordinates. I am trying to place a marker on each of the coordinates from the document. The problem is that the lengths of the documents change and the way I have it, the marker gets replaced with every iteration. How do I add a marker for each lat/lon point?
Here's the relevant code:
private GMapOverlay gMapOverlay;
private GMapMarker marker;
gmap.MapProvider = GMap.NET.MapProviders.GoogleMapProvider.Instance;
gmap.MinZoom = 2;
gmap.MaxZoom = 25;
gmap.Zoom = 5;
gmap.ShowCenter = false;
gmap.DragButton = MouseButtons.Left;
//setup the map overlay for displaying routes/points
gMapOverlay = new GMapOverlay("Path");
gmap.Overlays.Add(gMapOverlay);
gMapOverlay.Markers.Clear();
gMapOverlay.Routes.Clear();
//GMarkerGoogle marker = new GMarkerGoogle(new PointLatLng(0, 0), GMarkerGoogleType.green);
marker = new GMarkerGoogle(new PointLatLng(0, 0), GMarkerGoogleType.green);
marker.IsVisible = false;
marker.ToolTipMode = MarkerTooltipMode.OnMouseOver;
marker.ToolTipText = "Starting Point";
gMapOverlay.Markers.Add(marker);
private void btn_KMLFile_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog4.ShowDialog();
if (result == DialogResult.OK)
{
string filename = openFileDialog4.FileName;
string[] lines = System.IO.File.ReadAllLines(filename);
foreach (string line in lines)
{
string[] Data_Array = line.Split(',');
Double londecimal = Convert.ToDouble(Data_Array[0]);
Double latdecimal = Convert.ToDouble(Data_Array[1]);
marker.Position = new PointLatLng(latdecimal, londecimal);
marker.IsVisible = true;
gmap.Update();
}
}
}
private void openFileDialog4_FileOk(object sender, CancelEventArgs e)
{
OpenFileDialog openFileDialog4 = new OpenFileDialog();
}
The markers can go into the Markers collection:
public readonly ObservableCollection<GMapMarker> Markers;
Just add the markers to the collection as you do with your single marker.
EDIT
I was assuming a WPF client, so there's no Observable Collection if you are using WinForms. Have you tried to add a new marker to the collection as you do with your original marker? So in your loop:
string[] Data_Array = line.Split(',');
Double londecimal = Convert.ToDouble(Data_Array[0]);
Double latdecimal = Convert.ToDouble(Data_Array[1]);
// add a new one here
var marker = new GMarkerGoogle(new PointLatLng(latdecimal, londecimal), GMarkerGoogleType.green);
marker.IsVisible = true;
gMapOverlay.Markers.Add(marker);
I can fix with using list
List<GMapMarker> lMarks = new List<GMapMarker>();
int[] SelectedRows = gvProjects.GetSelectedRows();
map.Overlays.Clear();
GMapOverlay markers = new GMapOverlay("markers");
for (int i = 0; i < SelectedRows.Length; i++)
{
if (SelectedRows[i] >= 0)
{
double lat = Convert.ToDouble(gvProjects.GetRowCellValue(i-2,"Altitude"));
double lng = Convert.ToDouble(gvProjects.GetRowCellValue(i-2, "Longitude"));
PointLatLng point = new PointLatLng(lat, lng);
GMapMarker marker = new GMarkerGoogle(new PointLatLng(lat,lng),GMarkerGoogleType.yellow_pushpin);
marker.ToolTipMode = MarkerTooltipMode.Always;
marker.Tag = gvProjects.GetRowCellValue(i-2, "ID").ToString();
marker.ToolTipText = gvProjects.GetRowCellValue(i-2, "ProjectName").ToString();
lMarks.Add(marker);
}
}
markers.Markers.AddRange(lMarks);
map.Overlays.Add(markers);

programmatically create panel and add picture boxes

I want to programmatically create a panel and add some pictureBoxes where i select the image through a for loop. I tried lots of ways but the form shows empty.
My code is :
private void draw_pipeline()
{
Panel pnl = new Panel();
pnl.Size = new System.Drawing.Size(1130, 145);
pnl.Location = new Point(380, 260);
pnl.BorderStyle = BorderStyle.FixedSingle;
for (int i =0; i<3; i++)
{
PictureBox pic = new PictureBox();
pic.SizeMode = PictureBoxSizeMode.Zoom;
switch (i)
{
case 0:
{
pic.Location = new Point(3, 15);
pic.Size = new Size(73, 121);
pic.Image = new Bitmap("if.png"); break;
}
case 1:
{
pic.Location = new Point(76, 15);
pic.Size = new Size(73, 121);
pic.Image = new Bitmap("line.png"); break;
}
}
pnl.Controls.Add(pic);
}
}
the result i want to create is illustrated in the picture below, that contains two picture boxes with two images, if.png which is the if-box image and the line.png which is the line image. I repeat the result of my code is that form shows empty!! Any help?
You'll need to add the Panel to the Form at some point, in the same way you're adding PictureBoxes to the Panel:
this.Controls.Add(pnl);
(The this is assuming that your draw_pipeline method belongs to the Form to which you're trying to add the Panel.)

transition between images for picturebox in c# [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Transition of images in Windows Forms Picture box
I use the code below to change images in a picturebox every 5 seconds, but it's not looking good when changing an image: I want a transition effect between images.
Used Code
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Bitmap[] pictures = new Bitmap[9];
pictures[0] = new Bitmap(#"Library Images\cf3.jpg");
pictures[1] = new Bitmap(#"Library Images\cf4.jpg");
pictures[2] = new Bitmap(#"Library Images\l1.JPG");
pictures[3] = new Bitmap(#"Library Images\l2.JPG");
pictures[4] = new Bitmap(#"Library Images\l3.JPG");
pictures[5] = new Bitmap(#"Library Images\l4.JPG");
pictures[6] = new Bitmap(#"Library Images\l5.JPG");
pictures[7] = new Bitmap(#"Library Images\l6.JPG");
pictures[8] = new Bitmap(#"Library Images\l7.JPG");
Random random = new Random();
while (true)
{
int attempt = random.Next(0, pictures.Length);
pictureBox1.Image = pictures[attempt];
System.Threading.Thread.Sleep(5000);
}
}
example code greatly appreciated thanks in advance...
Simply take new code file and paste below code in it
an original answer for the similar question, answer taken from another question
Answer
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class BlendPanel : Panel
{
private Image mImg1;
private Image mImg2;
private float mBlend;
public BlendPanel()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
public Image Image1
{
get { return mImg1; }
set { mImg1 = value; Invalidate(); }
}
public Image Image2
{
get { return mImg2; }
set { mImg2 = value; Invalidate(); }
}
public float Blend
{
get { return mBlend; }
set { mBlend = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
if (mImg1 == null || mImg2 == null)
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height));
else
{
Rectangle rc = new Rectangle(0, 0, this.Width, this.Height);
ColorMatrix cm = new ColorMatrix();
ImageAttributes ia = new ImageAttributes();
cm.Matrix33 = mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg2, rc, 0, 0, mImg2.Width, mImg2.Height, GraphicsUnit.Pixel, ia);
cm.Matrix33 = 1F - mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg1, rc, 0, 0, mImg1.Width, mImg1.Height, GraphicsUnit.Pixel, ia);
}
base.OnPaint(e);
}
}
Build your project. You can now drop a BlendPanel from the top of the toolbox onto your form. Here's a sample program that uses it:
private float mBlend;
private int mDir = 1;
public int count = 0;
public Bitmap[] pictures;
public void myPhoto()
{
pictures = new Bitmap[9];
pictures[0] = new Bitmap(#"Library Images\cf3.jpg");
pictures[1] = new Bitmap(#"Library Images\cf4.jpg");
pictures[2] = new Bitmap(#"Library Images\l1.JPG");
pictures[3] = new Bitmap(#"Library Images\l2.JPG");
pictures[4] = new Bitmap(#"Library Images\l3.JPG");
pictures[5] = new Bitmap(#"Library Images\l4.JPG");
pictures[6] = new Bitmap(#"Library Images\l5.JPG");
pictures[7] = new Bitmap(#"Library Images\l6.JPG");
pictures[8] = new Bitmap(#"Library Images\l7.JPG");
timer1.Interval = 50; //time of transition
timer1.Tick += BlendTick;
try
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
catch
{
}
timer1.Enabled = true;
}
private void BlendTick(object sender, EventArgs e)
{
mBlend += mDir * 0.02F;
if (mBlend > 1)
{
mBlend = 0.0F;
if ((count + 1) < pictures.Length)
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
else
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[0];
count = 0;
}
}
blendPanel1.Blend = mBlend;
}
You'll need to modify the new Bitmap(#"yourimagePath"); calls. Build and run. You should see the displayed image smoothly morph from your first image to your second image without any flickering.
I hope it helps for other...

Custom Message Box

Is it possible to create my own custom MessageBox where I would be able to add images instead of only strings?
I also wanted this feature, so I created WPFCustomMessageBox, a WPF clone of the native Windows/.NET MessageBox which supports extra features like custom button text.
WPFCustomMessageBox uses static methods just like the standard .NET MessageBox, so you can plug-and-play the new library without modifying any code. Most importantly, I designed this control so it looks identical to the original MessageBox.
I created this library because I wanted to use verbs for my MessageBox buttons to help users better understand the functionality of the buttons. With this library, you can offer your users button descriptions like Save/Don't Save or Eject Fuel Rods/Don't do it! rather than the standard OK/Cancel or Yes/No (although you can still use those too, if you like).
The WPFCustomMessageBox message boxes return standard .NET MessageBoxResults. It also offers the same features as the original MessageBox like MessageBoxIcons and custom message box captions.
WPFCustomMessageBox is open source, so you can grab the code or make improvements here: https://github.com/evanwon/WPFCustomMessageBox
You can add WPFCustomMessage to your project via NuGet: https://www.nuget.org/packages/WPFCustomMessageBox/
Here is the code needed to create your own message box:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MyStuff
{
public class MyLabel : Label
{
public static Label Set(string Text = "", Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color())
{
Label l = new Label();
l.Text = Text;
l.Font = (Font == null) ? new Font("Calibri", 12) : Font;
l.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor;
l.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor;
l.AutoSize = true;
return l;
}
}
public class MyButton : Button
{
public static Button Set(string Text = "", int Width = 102, int Height = 30, Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color())
{
Button b = new Button();
b.Text = Text;
b.Width = Width;
b.Height = Height;
b.Font = (Font == null) ? new Font("Calibri", 12) : Font;
b.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor;
b.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor;
b.UseVisualStyleBackColor = (b.BackColor == SystemColors.Control);
return b;
}
}
public class MyImage : PictureBox
{
public static PictureBox Set(string ImagePath = null, int Width = 60, int Height = 60)
{
PictureBox i = new PictureBox();
if (ImagePath != null)
{
i.BackgroundImageLayout = ImageLayout.Zoom;
i.Location = new Point(9, 9);
i.Margin = new Padding(3, 3, 2, 3);
i.Size = new Size(Width, Height);
i.TabStop = false;
i.Visible = true;
i.BackgroundImage = Image.FromFile(ImagePath);
}
else
{
i.Visible = true;
i.Size = new Size(0, 0);
}
return i;
}
}
public partial class MyMessageBox : Form
{
private MyMessageBox()
{
this.panText = new FlowLayoutPanel();
this.panButtons = new FlowLayoutPanel();
this.SuspendLayout();
//
// panText
//
this.panText.Parent = this;
this.panText.AutoScroll = true;
this.panText.AutoSize = true;
this.panText.AutoSizeMode = AutoSizeMode.GrowAndShrink;
//this.panText.Location = new Point(90, 90);
this.panText.Margin = new Padding(0);
this.panText.MaximumSize = new Size(500, 300);
this.panText.MinimumSize = new Size(108, 50);
this.panText.Size = new Size(108, 50);
//
// panButtons
//
this.panButtons.AutoSize = true;
this.panButtons.AutoSizeMode = AutoSizeMode.GrowAndShrink;
this.panButtons.FlowDirection = FlowDirection.RightToLeft;
this.panButtons.Location = new Point(89, 89);
this.panButtons.Margin = new Padding(0);
this.panButtons.MaximumSize = new Size(580, 150);
this.panButtons.MinimumSize = new Size(108, 0);
this.panButtons.Size = new Size(108, 35);
//
// MyMessageBox
//
this.AutoScaleDimensions = new SizeF(8F, 19F);
this.AutoScaleMode = AutoScaleMode.Font;
this.ClientSize = new Size(206, 133);
this.Controls.Add(this.panButtons);
this.Controls.Add(this.panText);
this.Font = new Font("Calibri", 12F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Margin = new Padding(4);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new Size(168, 132);
this.Name = "MyMessageBox";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.ResumeLayout(false);
this.PerformLayout();
}
public static string Show(Label Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null)
{
List<Label> Labels = new List<Label>();
Labels.Add(Label);
return Show(Labels, Title, Buttons, Image);
}
public static string Show(string Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null)
{
List<Label> Labels = new List<Label>();
Labels.Add(MyLabel.Set(Label));
return Show(Labels, Title, Buttons, Image);
}
public static string Show(List<Label> Labels = null, string Title = "", List<Button> Buttons = null, PictureBox Image = null)
{
if (Labels == null) Labels = new List<Label>();
if (Labels.Count == 0) Labels.Add(MyLabel.Set(""));
if (Buttons == null) Buttons = new List<Button>();
if (Buttons.Count == 0) Buttons.Add(MyButton.Set("OK"));
List<Button> buttons = new List<Button>(Buttons);
buttons.Reverse();
int ImageWidth = 0;
int ImageHeight = 0;
int LabelWidth = 0;
int LabelHeight = 0;
int ButtonWidth = 0;
int ButtonHeight = 0;
int TotalWidth = 0;
int TotalHeight = 0;
MyMessageBox mb = new MyMessageBox();
mb.Text = Title;
//Image
if (Image != null)
{
mb.Controls.Add(Image);
Image.MaximumSize = new Size(150, 300);
ImageWidth = Image.Width + Image.Margin.Horizontal;
ImageHeight = Image.Height + Image.Margin.Vertical;
}
//Labels
List<int> il = new List<int>();
mb.panText.Location = new Point(9 + ImageWidth, 9);
foreach (Label l in Labels)
{
mb.panText.Controls.Add(l);
l.Location = new Point(200, 50);
l.MaximumSize = new Size(480, 2000);
il.Add(l.Width);
}
Labels.ForEach(l => l.MinimumSize = new Size(Labels.Max(x => x.Width), 1));
mb.panText.Height = Labels.Sum(l => l.Height);
mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight);
mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300);
LabelWidth = mb.panText.Width;
LabelHeight = mb.panText.Height;
//Buttons
foreach (Button b in buttons)
{
mb.panButtons.Controls.Add(b);
b.Location = new Point(3, 3);
b.TabIndex = Buttons.FindIndex(i => i.Text == b.Text);
b.Click += new EventHandler(mb.Button_Click);
}
ButtonWidth = mb.panButtons.Width;
ButtonHeight = mb.panButtons.Height;
//Set Widths
if (ButtonWidth > ImageWidth + LabelWidth)
{
Labels.ForEach(l => l.MinimumSize = new Size(ButtonWidth - ImageWidth - mb.ScrollBarWidth(Labels), 1));
mb.panText.Height = Labels.Sum(l => l.Height);
mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight);
mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300);
LabelWidth = mb.panText.Width;
LabelHeight = mb.panText.Height;
}
TotalWidth = ImageWidth + LabelWidth;
//Set Height
TotalHeight = LabelHeight + ButtonHeight;
mb.panButtons.Location = new Point(TotalWidth - ButtonWidth + 9, mb.panText.Location.Y + mb.panText.Height);
mb.Size = new Size(TotalWidth + 25, TotalHeight + 47);
mb.ShowDialog();
return mb.Result;
}
private FlowLayoutPanel panText;
private FlowLayoutPanel panButtons;
private int ScrollBarWidth(List<Label> Labels)
{
return (Labels.Sum(l => l.Height) > 300) ? 23 : 6;
}
private void Button_Click(object sender, EventArgs e)
{
Result = ((Button)sender).Text;
Close();
}
private string Result = "";
}
}
This took me 2 days to write. I hope it works for anyone that needs it.
I've implemented a WPF MessageBox fully customizable via standard WPF control templates:
http://blogs.microsoft.co.il/blogs/arik/archive/2011/05/26/a-customizable-wpf-messagebox.aspx
Features
The class WPFMessageBox has the exact same interface as the current WPF MessageBox class.
Implemented as a custom control, thus fully customizable via standard WPF control templates.
Has a default control template which looks like the standard MessageBox.
Supports all the common types of message boxes: Error, Warning, Question and Information.
Has the same “Beep” sounds as when opening a standard MessageBox.
Supports the same behavior when pressing the Escape button as the standard MessageBox.
Provides the same system menu as the standard MessageBox, including disabling the Close button when the message box is in Yes-No mode.
Handles right-aligned and right-to-left operating systems, same as the standard MessageBox.
Provides support for setting the owner window as a WinForms Form control.
Sure. I've done it by subclassing System.Windows.Window and adding the capacity to show various kinds of content (images, text and controls), and then calling ShowDialog() on that Window:
public partial class MyMessageBox : Window
{
// perhaps a helper method here
public static bool? Show(String message, BitmapImage image)
{
// NOTE: Message and Image are fields created in the XAML markup
MyMessageBox msgBox = new MyMessageBox() { Message.Text = message, Image.Source = image };
return msgBox.ShowDialog();
}
}
In the XAML, something like this:
<Window>
<DockPanel>
<Image Name="Image" DockPanel.Dock="Left" />
<TextBlock Name="Message" />
</DockPanel>
</Window>
I was in need like you and I have found this source and modified the way I wanted and you could get the most benefit out of it
here is the link
this is what it looks like by default:

Categories

Resources