Add Image in a stackpanel based on textbox input - c#

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);
}

Related

Grid child is already another visual or the root of a compositionTarget

I want in set all images from list to grid. But I have problem with adding second image in grid with Children.Add.
Here is my example:
List<Image> images = new List<Image>(8);
images.AddRange(Enumerable.Repeat(new Image(), 8));//8 empty images
Then setting images:
foreach (var image in images)
{
BitmapImage b = new BitmapImage();
b.BeginInit();
b.UriSource = new Uri("path");
b.EndInit();
image.Source = b;
image.Width = 50;
image.Height = 50;
}
Then in one function call like this:
private void put_images()
{
int i = 0;
foreach (var image in images)
{
Grid.SetRow(image, i);
Grid.SetColumn(image, i);
LayoutRoot.Children.Add(image);//here is error
i++;
}
}
I got runtime error: Additional information: Specified Visual is already a child of another Visual or the root of a CompositionTarget.
I don't understand why, because I got 8 different images, and I don't know how to fix that problem.
The problem is the code where you create the images.
images.AddRange(Enumerable.Repeat(new Image(), 8));
This is one image object, with 8 references in the collection.
The documentation of Enumerable.Repeat says:
element
Type: TResult
The value to be repeated.
The value of new Image() is the reference to that Image.
Which means you have 8 references to the same object in the collection.
You can easily verify that by comparing the first with the second entry in the list.
images[0] == images[1] //=true
A solution would be to use a for loop to instantiate the images.
for(int i = 0; i < 8; i++) images.Add(new Image());
It's seems the problem is the creating images.
Now I don't create 8 empty images, but I create Image, and then add in list. Now it's work:
for(int i = 0; i < 8; i++)
{
Image a = new Image();
BitmapImage b = new BitmapImage();
b.BeginInit();
b.UriSource = new Uri("path");
b.EndInit();
a.Source = b;
a.Width = 50;
a.Height = 50;
images.Add(a);
}

Call a children element of a StackPanel in C#

for some reasons I have to manipulated some Images within a stackpanel in-code (not in XAML)
<StackPanel x:Name="spImageList"
Orientation="Horizontal"
HorizontalAlignment="Center"
Canvas.ZIndex="1" />
and code to manipulate images:
public void ManipulateArrows()
{
spImageList.Children.Clear();
for (int i=0;i<cout;i++)
{
Image img = new Image();
img.Name = "img" + i.ToString();
img.Source = new BitmapImage(new Uri("/Assets/Image/arrow_blue.png", UriKind.Relative));
spImageList.Children.Add(img);
}
}
Now I need to change the source of the images in that stackpanel, so how can i do it ?
public void ChangeImage(string name)
{
spImageList.Children .. = new BitmapImage(new Uri("/Assets/Image/arrow_red.png", UriKind.Relative));;
// Get the image by the name like "img1","img2"
}
Try this:
public void ChangeImages()
{
for (int j = 0; j < spImageList.Children.Count; j++)
{
Image img = (Image)Stack.FindName("img"+j.ToString());
img.Source = new BitmapImage(new Uri("/Assets/Image/arrow_red.png", UriKind.Relative));
}
}
You can use FindName method,
Image imag1 = (Image)spImageList.FindName("img1");
Image imag2 = (Image)spImageList.FindName("img2");

Add multiple images to canvas with C#

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);
}

Transformation in xaml for windows 8

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.

WP8 Error When Trying to Re-Add Push-Pins on Zoom

When I try to zoom in (Button_Click_1 event) I'm getting an error as I try to add images/layers back to a map.
I should note: I've simplified the code substantially so that it would be easier to pick out the error (that I can't seem to figure out).
Each zoom level has a different set of images which are attached to it in case you're wondering why I need to continually clear the layers/images.
Each of the Images/Layers/Overlays is defined globally (so that I can use them in several methods
Image img1 = new Image();
Image img2 = new Image();
MapLayer lyr1 = new MapLayer();
MapLayer lyr2 = new MapLayer();
MapOverlay ovrly1 = new MapOverlay();
MapOverlay ovrly2 = new MapOverlay();
Each of these is initialized when the page loads in a separate method:
private void initializeImages()
{
ovrly1.GeoCoordinate = new GeoCoordinate(49.33783000, -0.45215600);
img1.Source = new BitmapImage(new Uri("images/push-pin.png", UriKind.Relative));
ovrly1.Content = img1;
ovrly1.PositionOrigin = new Point(0.0, 0.0);
img1.Opacity = 0.8;
img1.Height = 30;
img1.Width = 30;
img1.Tap += img1_Tap;
ovrly2.GeoCoordinate = new GeoCoordinate(49.35783000, -0.45425600);
img2.Source = new BitmapImage(new Uri("images/push-pin.png", UriKind.Relative));
ovrly2.Content = img2;
ovrly2.PositionOrigin = new Point(0.0, 0.0);
img2.Opacity = 0.8;
img2.Height = 30;
img2.Width = 30;
img2.Tap += img2_Tap;
}
When I try to zoom on the Button_Click the first time it works fine. But any other time I try to zoom I get an error:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
map1.ZoomLevel += 1;
map1.Layers.Clear();
lyr1.Add(ovrly1); // ERROR OCCURS HERE
map1.Layers.Add(lyr1);
lyr2.Add(ovrly2);
map1.Layers.Add(lyr2);
}
This error disappears when I declare all of the images/overlays/layers 'locally' inside the Button_Click event. But I can't do that, otherwise I won't be able to access the Images outside of the method.
Any help would be greatly appreciated.
I think the problem is that you are adding many overlays on exactly same position.
Additionaly, in the Button Click event you clear the Layers element of the map, but you don't do the same with each layer, adding new elements to to the layer which already have one, each time. Since you add the elements in the same position, you get the error.
Following code should work if both elements have different GeoCoordinate values:
private void Botoia_Click(object sender, RoutedEventArgs e)
{
map1.ZoomLevel += 1;
map1.Layers.Clear();
lyr1.Clear();
lyr2.Clear();
lyr1.Add(ovrly1);
map1.Layers.Add(lyr1);
lyr2.Add(ovrly2);
map1.Layers.Add(lyr2);
}

Categories

Resources