Basically i am trying to make a windows phone application where one by one images can be added on the canvas but the following code doesnt seem to work
private void AddImage_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask chooseImage = new PhotoChooserTask();
chooseImage.Completed += chooseImage_Completed;
chooseImage.Show();
}
public void chooseImage_Completed(object sender, PhotoResult e)
{
if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
{
return;
}
Image img = new Image();
SelectedBitmap = new WriteableBitmap(60,60);
img.Width = 100;
img.Height = 100;
img.Name = "img";
SelectedBitmap.SetSource(e.ChosenPhoto);
img.Source = SelectedBitmap;
e.ChosenPhoto.Position = 0;
CollageCanvas.Children.Add(img);
Canvas.SetTop(img,50);
Canvas.SetLeft(img,50);
}
the first time the button is clicked, image is successfully added to the canvas but when i attempt to add another image to the canvas it gives the following exception :-
"An exception of type 'System.ArgumentException' occurred in System.Windows.ni.dll but was not handled in user code
Additional information: Value does not fall within the expected range."
So i want to know how can i change my program to be able to add multiple images to the canvas.
I think it has something to do with the fact that the name property of each child element has to be unique. I think this should work for you.
private int index = 1;
public void chooseImage_Completed(object sender, PhotoResult e)
{
if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
{
return;
}
Image img = new Image();
WriteableBitmap SelectedBitmap = new WriteableBitmap(60, 60);
img.Width = 100;
img.Height = 100;
img.Name = "img";
SelectedBitmap.SetSource(e.ChosenPhoto);
img.Source = SelectedBitmap;
img.Name = "Photo " + index++; // Set unique name here
e.ChosenPhoto.Position = 0;
CollageCanvas.Children.Add(img);
Canvas.SetTop(img, 50);
Canvas.SetLeft(img, 50);
}
Related
I am creating dynamic images on canvas . T want to translate them and rotate them on button click . Translating working fine but when I rotating it its gives error like this
Additional information:
Unable to cast object of type
'Windows.UI.Xaml.Media.TranslateTransform'
to type
'Windows.UI.Xaml.Media.RotateTransform'.
Here is my code
Image i = new Image(); // Global variable for selecting
private void btn_Click(object sender, RoutedEventArgs e) // For creating images
{
int i = 0;
Image image = new Image();
string url = "ms-appx:///Assets/1.png";
BitmapImage bm = new BitmapImage();
bm.UriSource = new Uri(url, UriKind.Absolute);
image.Source = bm;
image.Height = Double.NaN;
image.Width = Double.NaN;
image.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.TranslateY | ManipulationModes.Rotate;
image.RenderTransform = new TranslateTransform();
image.Name = "img" + i;
image.Tapped += select;
image.ManipulationDelta += DragableItem_ManipulationDelta;
DrawCanvas.Children.Add(image);
i++;
}
private void select(object sender, TappedRoutedEventArgs e) // selecting of image
{
i = (Image)sender;
}
private void rotate_Click(object sender, RoutedEventArgs e) //rotating
{
if (i != null)
{
var translate = (RotateTransform)i.RenderTransform;
translate.CenterY = 0;
translate.CenterX = 0;
translate.Angle = 45;
i.RenderTransform = translate;
}
}
void DragableItem_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) // translating code
{
var name = (Image)sender;
var translate = (TranslateTransform)name.RenderTransform;
translate.X += e.Delta.Translation.X;
translate.Y += e.Delta.Translation.Y;
}
need help stuck here for a long time ??
You are setting your RenderTransform to a TranslateTransform and then trying to cast it to a RotateTransform (as the error states). You should probably use a CompositeTransform instead or use a TransformGroup with both of the transform types in it.
My form has two objects: a background image that takes up the entire screen, and a dragable dialog control that only takes up a portion of the screen. I am using Mouse events for dragging and dropping the dialog control within the background image.
My problem is that while dragging, there is a copy of the control that is visible at it's previous location.
What is causing this shadow copy to appear, and how can I prevent it from happening?
My code looks something like this:
private void dialog_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
_dialogDragStart = e.Location;
dialog.MouseMove += new MouseEventHandler(dialog_MouseMove);
}
}
private void dialog_MouseUp(object sender, MouseEventArgs e)
{
dialog.MouseMove -= new MouseEventHandler(dialog_MouseMove);
_isDragging.Value = false;
}
private void dialog_MouseMove(object sender, MouseEventArgs e)
{
var difference = new Point(e.Location.X - _dialogDragStart.X, e.Location.Y - _dialogDragStart.Y);
if (!_isDragging.Value)
{
if (Math.Abs(difference.X) > SystemInformation.DragSize.Width || Math.Abs(difference.Y) > SystemInformation.DragSize.Height)
{
_isDragging.Value = true;
}
}
else if (_isDragging.Value && !difference.IsEmpty)
{
DialogOffset = GetValidDialogOffset(DialogOffset.X + difference.X, DialogOffset.Y + difference.Y);
this.Invalidate();
this.Update();
}
}
It should be noted that this entire UserControl contains a custom OnPaint event. The Paint event recalculates the Size and Location of the Dialog before painting it in a custom format. To get this working, I have simply adjusted the Location calculation to include the DialogOffset.
const int padding = 1;
const int shadowDepth = 3;
const int roudeCornerRadius = 5;
private void Paint(Graphics g, Rectangle clipRect)
{
try
{
dialog.Size = GetSize();
dialog.Location = new Point(
((backgroundImage.Width - dialog.Width) / 2) + DialogOffset.X,
((backgroundImage.Height - dialog.Height) / 2) + DialogOffset.Y);
if (Image != null && !backgroundImage.ClientRectangle.IsEmpty)
{
Rectangle imageBounds = new Rectangle(Point.Empty, Image.Size);
using (BufferedGraphics buffer = BufferedGraphicsManager.Current.Allocate(g, backgroundImage.ClientRectangle))
{
using (Bitmap img = ((Bitmap)backgroundImage).Clone(imageBounds, PixelFormat.Format16bppArgb1555) as Bitmap)
{
buffer.Graphics.Clear(Color.White);
buffer.Graphics.DrawImage(img,backgroundImage.ClientRectangle, imageBounds, GraphicsUnit.Pixel);
buffer.Render(g);
}
}
}
//Create Rectangles
Rectangle outerRect = dialog.ClientRectangle;
Rectangle innerRect = new Rectangle(padding, padding, outerRect.Width - (padding + shadowDepth), outerRect.Height - (padding + shadowDepth));
//create Paths
using (GraphicsPath innerPath = new GraphicsPath())
{
GraphicsHelper.GetRoundedRect(innerPath, innerRect, roudeCornerRadius, 1, 1);
//Assign outer rounded rectangle to the dialog's region property
Region region = new Region(innerPath);
if (dialog.Region != null)
dialog.Region.Dispose();
dialog.Region = region;
}
}
catch (Exception ex)
{
// Log error
}
}
I've seen suggestions to set the DoubleBufferred property to true, however its explicitly set to false in the existing code, and setting it to true causes no update at all while dragging.
I've tried taking a screenshot of the problem, however all screenshots only show one copy of the dialog control being dragged, even though I can clearly see a 2nd copy of the control on my screen while dragging.
What can be causing this, and how can I fix it?
I'm trying to add Image stored in ..\Resources\ebi.png in a stackpanel. Most of the times, the same image will be displayed in Stackpanel, depending on Textbox input "EtReqCount". Below is the sample code tried but getting error saying
"Specified Visual is already a child of another Visual or the root of a CompositionTarget"
Below is the code tried:
private BitmapImage bmp = new BitmapImage(new Uri("WpfApplication1;component/Resources/ebi.png", UriKind.RelativeOrAbsolute));
private void EtReqCount_TextChanged(object sender, TextChangedEventArgs e)
{
StackPanel dynamicStackPanel = new StackPanel();
dynamicStackPanel.Width = 300;
dynamicStackPanel.Height = 200;
dynamicStackPanel.Background = new SolidColorBrush(Colors.LightBlue);
dynamicStackPanel.Orientation = Orientation.Vertical;
if (EtReqCount.Text != "")
{
for (int k = 1; k <= Int32.Parse(EtReqCount.Text); k++)
{
Image img = new System.Windows.Controls.Image(); // This makes the difference.
img.Source = bmp;
dynamicStackPanel.Children.Add(img);
}
}
}
XAML Code:
It is apparent. The same image is already a child of the StackPanel, you cannot add it again and again.
Moreover, you should use a private memeber to hold the repetitively used bmp to save resource:
outside the class method, and inside class.cs:
private BitmapImage bmp=new BitmapImage(new Uri("/....../ebi.png", UriKind.RelativeOrAbsolute);
You can create new instances of the image:
for(int i=0; i<...;i++)
{
img = new System.Windows.Controls.Image(); // This makes the difference.
img.Source = bmp;
dynamicStackPanel.Children.Add(img);
}
I have created a function that loops a folder and retrieves each image file and draw a picturebox on the form.
Here is the function :
private void Create_Controls(string Img_path)
{
PictureBox p = new PictureBox();
p.Size = new Size(138, 100);
p.Location = new Point(6, 6);
p.BackgroundImage = Image.FromFile(Img_path);
p.BackgroundImageLayout = ImageLayout.Stretch;
this.Controls.Add(p);
}
So what i need to do is : whenever i click on any picturebox on the form , a message popup with the image file path.
So i thought about adding a custom event :
p.Click += delegate { Pop_Up(); };
AND
private void Pop_Up()
{
/* POP UP MESSAGE WITH Picturebox image file path*/
}
You need to use the property ImageLocation of the PictureBox . The property gets or sets the path or URL for the image to display in the PictureBox.
Just do the following:
p.Click += new EventHandler(Pop_Up);
...
private void Pop_Up(object sender, EventArgs e)
{
var pb = sender as PictureBox;
if(pb != null)
MessageBox.Show(pb.ImageLocation);
}
You could use Tag property for this.
something like this .
private void Create_Controls(string Img_path)
{
PictureBox p = new PictureBox();
p.Size = new Size(138, 100);
p.Location = new Point(6, 6);
p.Tag = Img_path;
p.BackgroundImage = Image.FromFile(Img_path);
p.BackgroundImageLayout = ImageLayout.Stretch;
this.Controls.Add(p);
}
private void Pop_Up()
{
MessageBox.Show(p.Tag);
}
For more on this Go here.
Then along with what HatSoft says, change your Pop_up() method like:
private void Pop_Up(object sender, EventArgs e)
{
MessageBox.Show(((PictureBox)sender).ImageLocation);
}
But maybe a bit more elegant and checking if it is indeed a PictureBox etc.
I am trying to make a trackbar which will zoom in and out on a picture in a picturebox. This is my current code:
namespace Zoom_in_and_Out_Tool
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Image imgOriginal;
private void Form1_Load(object sender, EventArgs e)
{
// set image location
imgOriginal = Image.FromFile(#"C:\New Folder\picture1.jpg");
picBox.Image = imgOriginal;
// set Picture Box Attributes
picBox.BackgroundImageLayout = ImageLayout.Stretch;
// set Slider Attributes
zoomSlider.Minimum = 1;
zoomSlider.Maximum = 5;
zoomSlider.SmallChange = 1;
zoomSlider.LargeChange = 1;
zoomSlider.UseWaitCursor = false;
// reduce flickering
this.DoubleBuffered = true;
}
public Image PictureBoxZoom(Image img, Size size)
{
Bitmap bm = new Bitmap(img, Convert.ToInt32(img.Width * size.Width), Convert.ToInt32(img.Height * size.Height));
Graphics grap = Graphics.FromImage(bm);
grap.InterpolationMode = InterpolationMode.HighQualityBicubic;
return bm;
}
private void zoomSlider_Scroll(object sender, EventArgs e)
{
if (zoomSlider.Value > 0)
{
picBox.Image = null;
picBox.Image = PictureBoxZoom(imgOriginal, new Size(zoomSlider.Value, zoomSlider.Value));
}
}
}
}
Currently it comes up with 2 problems. One being it does want to compile with the line grap.InterpolationMode = InterpolationMode.HighQualityBicubic; . The Second problem is that when i try to zoom it comes up with the error: " "ArgumentException was unhandled" error at the line: Bitmap bm = new Bitmap(img, Convert.ToInt32(img.Width * size.Width), Convert.ToInt32(img.Height * size.Height)); " Any help would be great,
Thanks
UPDATE
The first error says: "The name 'InterpolationMode' does not exist in the current context"
The second error when i comment this line out is: 'NullReferenceException was unhandled "Object reference not set to an instance of an object.' on the line Bitmap bm = new Bitmap(img, Convert.ToInt32(img.Width * size.Width), Convert.ToInt32(img.Height * size.Height));
Thanks
Include
using System.Drawing.Drawing2D;
in your using list.
The second error could be due to either the img being null or the size being null.
The first compiler error is more than likely caused by an unknown reference to InterpolationMode.HighQualityBicubic. The InterpolationMode enumeration is found in the Drawing2D namespace, which is a child namespace of System.Drawing.
You can fix this error either by adding an additional Using directive for System.Drawing.Drawing2D, or by fully qualifying the namespace in your code:
grap.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic;
The second problem with your code is that the image you're specifying as a parameter to this method (img) is a null reference. The Scroll event of your zoom slider is probably getting raised as soon as the control is created (in your form's constructor), which is before the code in your form's Load method is run, which is what creates the image (by loading it from a file on disk).
Try adding a null check to the Scroll event handler:
private void zoomSlider_Scroll(object sender, EventArgs e)
{
if ((zoomSlider.Value > 0) && (imgOriginal != null))
{
picBox.Image = null;
picBox.Image = PictureBoxZoom(imgOriginal, new Size(zoomSlider.Value, zoomSlider.Value));
}
}
Finally, I noticed that you're setting the BackgroundImageLayout property of the picture box, but none of the code you post is actually specifying a background image for the picture box. Did you mean to set the SizeMode property to adjust how the image is displayed? Something like:
picBox.SizeMode = PictureBoxSizeMode.StretchImage;