XAML:
<Grid x:Name="LayoutRoot" VerticalAlignment="Top">
<ScrollViewer x:Name="ScrollViewer1" Margin="0,0,0,0">
<StackPanel x:Name="myStackPanel"/>
</ScrollViewer>
</Grid>
C#:
Image[] image2 = new Image[30];
for (int n = 1; n <= 29; n++)
{
image2[n] = new Image();
BitmapImage bitmapa = downloadBitmap(n);
image2[n].Source = bitmapa;
myStackPanel.Children.Add(image2[n]);
}
I'm downloading BitmapImage from IsolatedSotrage -> downloadBitmap(n).
When I start the app I have a black image in my phone becouse photos are not visible(why?!), but when I lock the phone and unlock I have all the pictures, everything is ok.
When I remove ScrollViewer i don't have any problem.
Why this is happening? Please help me.
Dipak - I used the Grid - I hold each picture in a separate Grid:
Image[] image2 = new Image[30];
for (int n = 1; n <= 29; n++)
{
Grid myGrid = new Grid();
Image2[n] = new Image();
aktualizacja2 bitmapa = new aktualizacja2(n, path);
Image2[n].Source = bitmapa.getBitmap();
myGrid.Children.Add(Image2[n]);
myStackPanel.Children.Add(myGrid);
}
it works, but loading images takes much longer...
Related
I'm currently trying to insert random images onto a canvas using mouse click coordinates. However, I am unsure where the X & Y coordinates would be placed in the code. Any pointers would be great thanks!
private void canvas1_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Point p = Mouse.GetPosition(canvas1);
double x = p.X;
double y = p.Y;
Image myImage = new Image();
string[] imageNames = { "greenslime.png", "blueslime.png", "redslime.png", "yellowslime.png" };
var rand = new Random();
string imageName = imageNames[rand.Next(imageNames.Length)];
string imageSlime = string.Concat("", imageName);
myImage.Source = new BitmapImage(new Uri(imageSlime, UriKind.Relative));
myImage.Width = 200;
myImage.Height = 200;
canvas1.Children.Add(myImage);
}
You should use the Canvas.Top/Canvas.Left attached dependency properties.
In code behind you should use:
myImage.Source = new BitmapImage(new Uri(imageSlime, UriKind.Relative));
myImage.Width = 200;
myImage.Height = 200;
Canvas.SetLeft(myImage, x);
Canvas.SetTop(myImage, y);
canvas1.Children.Add(myImage);
Because the image is placed in the canvas, the canvas will use these properties.
In XAML it would be:
<Canvas x:Name="canvas1">
<Image Canvas.Top="10" Canvas.Left="20" Width="200" Height="200" />
</Canvas>
I have a collection of images i want to show with FlipView. On each image I want to draw multiple rectangles, but to do this I need the current dimensions for the image after it has been rendered. I have the coordinates for the rectangles in the same list as my images. I get the dimensions from the images via ImageOpened event, but the problem is the FlipView event loads three images at the same time causing the different rectangles all to be drawn on the first image. Any suggestions?
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
itemList = e.Parameter as List<TableData>;
foreach (var blobImage in itemList)
{
var request = (HttpWebRequest)WebRequest.Create($"http://localhost:58941/api/image?id={blobImage.ImageBlobName}");
request.Method = "GET";
request.ContentType = "application/json";
WebResponse response = await request.GetResponseAsync();
if (response != null)
{
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var myDict = JsonConvert.DeserializeObject<BlobImage>(responseString);
var jj = new MyImage(blobImage.ImageDescription, myDict.Uri, blobImage.GpsLatitude, blobImage.GpsLongitude, blobImage.GpsAltitude, blobImage.DateTime, blobImage.ObjectsDetected);
MyImages.Add(jj);
}
}
MyFlipView.ItemsSource = MyImages;
}
private void Image_ImageOpened(object sender, RoutedEventArgs e)
{
Image currentImageDimensions = sender as Image;
currentWidth = currentImageDimensions.ActualWidth;
currentHeight = currentImageDimensions.ActualHeight;
foreach (var imageRectangle in itemList)
{
for (int i = 0; i < imageRectangle.ObjectsDetected.Count; i++)
{
rectangle = new Rectangle();
var xMinConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].xMin);
var yMinConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].yMin);
var xMaxConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].xMax);
var yMaxConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].yMax);
var xMin = xMinConvert * currentWidth;
var yMin = yMinConvert * currentHeight;
var xMax = xMaxConvert * currentWidth;
var yMax = yMaxConvert * currentHeight;
rectangle.Height = yMax - yMin;
rectangle.Width = xMax - xMin;
var left = ((bgWidth - currentWidth) / 2) + xMin;
var top = ((bgHeight - currentHeight) / 2) + yMin;
rectangle.Margin = new Thickness(left, top, 0, 0);
rectangle.Stroke = new SolidColorBrush(Windows.UI.Colors.Red);
rectangle.StrokeThickness = 1;
layoutRoot.Children.Add(rectangle);
}
}
}
Xaml:
<ScrollViewer DoubleTapped="scrollViewer_DoubleTapped" MinZoomFactor="1" ZoomMode="Enabled" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid x:Name="cGrid" Width="{Binding ElementName=gridbg, Path=ActualWidth}" Height="{Binding ElementName=gridbg, Path=ActualHeight}">
<FlipView SelectionChanged="MyFlipView_SelectionChanged" Name="MyFlipView" Width="{Binding ElementName=gridbg, Path=ActualWidth}" Height="{Binding ElementName=gridbg, Path=ActualHeight}">
<FlipView.ItemTemplate>
<DataTemplate x:DataType="local:MyImage">
<Image Source="{Binding Image}" Stretch="Uniform" Height="{Binding ElementName=gridbg, Path=ActualHeight}" ImageOpened="Image_ImageOpened" />
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Border>
<Canvas x:Name="layoutRoot">
</Canvas>
</Grid>
</ScrollViewer>
but FlipView loads 3 images at a time
FlipView control supports virtualization at default, load three items at one time is as expected. If disabled the virtualization, all the items will be loaded into the FlipView at one time.
You have several ways to resolve your issue. Since you only need the Rectangle drawing when one FlipViewItem selected, you could put the drawing relative code snippet inside SelectionChanged event handle of FlipView. By doing this you may encounter the issue for getting the Image height and width. Actually you should be able to know the image metadata by getting StorageFile object from uri of the image. If you just want to get the Image control for getting the Height and Width, you may use VisualTreeHelper to get the Image control from FlipView.
Or you could consider to force load only one item to the FlipView each time. For this you could use ISupportIncrementalLoading for incremental loading.
I'm not sure what you are drawing these rectangles for, consider to draw these rectangles to the image before you binding the images to the FlipView if possible.
I have a window with that structure:
Then in the code behind of the window in the constructor I add the following code:
int numRow = 2;
int numColumn = 3;
for (int row = 0; row < numRow; row++)
{
var rd = new RowDefinition();
rd.Height = new GridLength(1.0, GridUnitType.Star);
grdMain.RowDefinitions.Add(rd);
}
for (int column = 0; column < numColumn; column++)
{
var cd = new ColumnDefinition();
cd.Width = new GridLength(1.0, GridUnitType.Star);
grdMain.ColumnDefinitions.Add(cd);
}
for (int row = 0; row < numRow; row++)
{
for (int column = 0; column < numColumn; column++)
{
//var borderImage = new Border();
//borderImage.BorderThickness = new Thickness(1);
//borderImage.BorderBrush = new SolidColorBrush(Colors.Red);
var finalImage = new Image();
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/EasyRun;component/Resources/Images/ITA.png");
logo.EndInit();
finalImage.Source = logo;
//borderImage.Child = finalImage;
Grid.SetRow(finalImage, row);
Grid.SetColumn(finalImage, column);
grdMain.Children.Add(finalImage);
}
by doing so I expect the window to resize rows and columns accordin to the size of the parent window. But what happens is that while the horizontal stretch works the vertical doesn't.
So in short what I'd like is the grid to stretch columns/rows according to its parent window size
Try using a dockpanel instead then a stack panel
<DockPanel Name="stpMain">
<Button DockPanel.Dock="Bottom" Content="AAA" Width="100" Click="Button_Click"></Button>
<Border BorderThickness="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0" BorderBrush="Red">
<Grid Name="grdMain"></Grid>
</Border>
I want to create the window that would show list of pictures one below the other. I've created control that contains ViewBox and Image in it:
<UserControl x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Viewbox Name="viewbox">
<Image Height="10" Name="image" Width="10" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Viewbox>
</Grid>
</UserControl>
public BitmapImage Image
{
get { return image.Source as BitmapImage; }
set { changeImage(value); }
}
public SingleIllustrationViewer()
{
InitializeComponent();
}
private void changeImage(BitmapImage img)
{
System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
float dpiX = graphics.DpiX / 96;
this.image.BeginInit();
this.image.Source = img;
this.image.EndInit();
this.image.Width = img.PixelWidth / img.DpiX * dpiX;
}
and I'm placing Images on window like this:
double margin = 0;
for (int i = 0; i < illustrations.Count; i++)
{
String path = illustrations[i].printVersions.Last<String>();
BitmapImage bmp = new BitmapImage(new Uri(path));
Controls.SingleIllustrationViewer iv = new Controls.SingleIllustrationViewer();
iv.VerticalAlignment = System.Windows.VerticalAlignment.Top;
iv.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
iv.Margin = new Thickness(50, margin, 0, 0);
iv.Image = bmp;
grid.Children.Add(iv);
margin += iv.Image.Height + 20;
}
So, for example, I've placed 3 pictures (all 3 of same width) like this, and received such an interesting behavior: first one is good, second smaller, third smaller than a second. Here is the screen shot:
Maybe someone can tell me why is that so, and how can fix this, to see all those picture in the same width?
Thanks!
Regards, Tomas
Root cause:
You did not specify the Height or Width of the UserControl, so when the first SingleIllustrationViewer is added to the Grid, it will be stretched to occupied all available space until it reaches the edge of the Grid. The same happens to the second one, but it is constrained to a smaller region due to the incremented margin.
The size specified as
d:DesignHeight="300" d:DesignWidth="300"
is only used by designer, set the size like
Height="300" Width="300"
And then, put you viewers in a StackPanel instead of a Grid, then you don't have to calculate the Margin of a viewer base on the last viewer's position. StackPanel is a container that stacks its children in one direction, vertically or horizontally.
for (int i = 0; i < illustrations.Count; i++)
{
String path = illustrations[i].printVersions.Last<String>();
BitmapImage bmp = new BitmapImage(new Uri(path));
Controls.SingleIllustrationViewer iv = new Controls.SingleIllustrationViewer();
iv.VerticalAlignment = System.Windows.VerticalAlignment.Top;
iv.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
iv.Margin = new Thickness(50, 0, 0, 20); //50 px to the left, 20 px to the next child
iv.Image = bmp;
stackPanel1.Children.Add(iv);
}
I need to show multiple buttons, but each one must have a different background than other buttons, I have been working on it, but I only got to display multiple buttons but with the same background.
Here is the XAML:
<Window x:Class="apple.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="370" Width="525">
<Grid>
<Image Source="C:\Users\Public\Pictures\Sample Pictures\Koala.jpg" Stretch="Fill"/>
<DockPanel Name="dock">
<UniformGrid Name="gridx" DockPanel.Dock="Top" Rows="3" Columns="3" Height="334">
</UniformGrid>
</DockPanel>
</Grid>
</Window>
Also, here is the C# code:
namespace apple
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
masterGUI();
}
public void masterGUI()
{
ImageBrush ib = new ImageBrush();
IconImage[] ico = null;
Bitmap[] img = null;
string[] list = null;
string[] link = Directory.GetFiles(#"C:\ProgramData\Microsoft\Windows\Start Menu\Programs", "*.lnk", SearchOption.AllDirectories);
list = new string[link.Length];
ico = new Icon[link.Length];
img = new Bitmap[link.Length];
for (int n = 0; n < link.Length; n++)
{
System.Windows.Controls.Button newBtn = new Button();
list[n] = System.IO.Path.GetFileNameWithoutExtension(link[n]);
FileToImageIconConverter some = new FileToImageIconConverter(link[n]);
ImageSource imgSource = some.Icon;
ib.ImageSource = imgSource;
newBtn.Background = ib;
newBtn.Content = list[n];
gridx.Children.Add(newBtn);
}
}
}
}
Any idea? thank you.
The ImageBrush needs to be created in the for-loop individually for each item. Otherwise you will end up with the same background for every item.
Also you are approaching this the "wrong" way, in WPF you should use data binding and data templating for this sort of thing instead of imperative looping.