How can I enlarge image in C# (exactly in UWP) after clicking on it?
I tried few things:
1) I tried to add button, with image content, what I want to enlarge, and then I added event Click. But I don't know what I should to add into that code.
2) i also tried to add image directly to my XAML page, and I wanted to create Tapped event, but again, I don't know what I should to add into that code.
I just want to create a small photogallery, so after clicking on image thumbnail will be opened larger image.
Or if there is any possibility to add pdf files, you can write it too. That's another solution of my problem.
You could enlarge the Image by settings its RenderTransform property to a ScaleTransform:
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
Image image = sender as Image;
image.RenderTransform = new ScaleTransform() { ScaleX = 2, ScaleY = 2 };
}
<Image Source="ms-appx:///Assets/pic.png" Tapped="Image_Tapped" Stretch="None" />
The ScaleX and ScaleY properties gets or sets the scaling factor. Please refer to the MSDN documentation for more information: https://msdn.microsoft.com/library/windows/apps/br242940?f=255&MSPPError=-2147217396
Looks good, but there is a problem. When I add more images, like into GridView, they are overlapping, and highlighted. Images can overlap, but image, which I click should be always on top...
You could put the tapped Image in a Popup then and then for example add it back to its original Panel when it is tapped again. I put together an example that should give you the idea and something to build on:
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
Image image = sender as Image;
Panel parent = image.Parent as Panel;
if (parent != null)
{
image.RenderTransform = new ScaleTransform() { ScaleX = 2, ScaleY = 2 };
parent.Children.Remove(image);
parent.Children.Add(new Popup() { Child = image, IsOpen = true, Tag = parent });
}
else
{
Popup popup = image.Parent as Popup;
popup.Child = null;
Panel panel = popup.Tag as Panel;
image.RenderTransform = null;
panel.Children.Add(image);
}
}
<GridView SelectionMode="None" isItemClickEnabled="True">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Image Source="ms-appx:///Assets/pic.png" Tapped="Image_Tapped" Stretch="None" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Related
Everything seems to be simple and there are quite a few tutorials, but I cannot transfer data (in my case, an image) to a wpf window element. I was able to implement the transfer of an image from one element to another. But when I capture an image (for example, a desktop), when I transfer it to the desired element, the transfer option does not even appear, only a crossed-out circle and does not work out more than one event associated with drop (as if AllowDrop = false)
My code:
XAML
<Image x:Name="mainContent" Grid.Column="1" Stretch="Fill" AllowDrop="True" Drop="MainContent_Drop" />
C#
private void SpImageLeft_MouseDown(object sender, MouseButtonEventArgs e)
{
Image image = sender as Image;
DragDrop.DoDragDrop(image, image, DragDropEffects.Copy);
}
private void MainContent_Drop(object sender, DragEventArgs e)
{
Image image = (Image)e.Data.GetData(typeof(Image));
mainContent.Source = image.Source;
}
I understand that when I take an image from explorer it will be different there, something like this, but it still does not even show that you can add an image
private void MainContent_Drop(object sender, DragEventArgs e)
{
string[] arr = (string[])e.Data.GetData(DataFormats.FileDrop);
mainContent.Source = (ImageSource)new ImageSourceConverter().ConvertFromString(arr[0]);
}
The following worked for me as a Drop event handler for an Image control:
private void OnMainImageDrop(object sender, DragEventArgs e)
{
if (sender is Image image && e.Data.GetDataPresent(DataFormats.FileDrop))
{
if (e.Data.GetData(DataFormats.FileDrop) is string[] filePaths)
{
image.Source.Freeze();
string filePath = filePaths[0];
var uriSource = new Uri(filePath);
var imageSource = new BitmapImage(uriSource);
image.Source = imageSource;
}
}
}
I used a placeholder image to make sure the image had a size and served as a mouse hover surface.
XAML:
<Image x:Name="MainImage" Grid.Row="1"
Source="Images/DotNetLogo.png"
Stretch="Uniform"
AllowDrop="True" Drop="OnMainImageDrop"/>
Introduction
I want to make the header button to be used to minimize items with a one click action, not double one
Screenshot of the header button
Source Code
StackPanel stackPanel = new StackPanel();
InitializeComponent();
NavigationView navigationView = new NavigationView();
navigationView.PaneDisplayMode = NavigationViewPaneDisplayMode.LeftMinimal;
navigationView.IsPaneOpen = false;
NavigationViewItem navigationViewItem = new NavigationViewItem();
void NavigationView(object sender, TappedRoutedEventArgs e)
{
navigationView.IsPaneOpen = true;
}
navigationViewItem.Icon = new SymbolIcon(Symbol.Admin);
navigationViewItem.Content = "Test";
navigationView.MenuItems.Add(navigationViewItem);
stackPanel.Children.Add(navigationView);
Content = stackPanel;
Problem
I want to run the code when the header button
clicked once, not twice, but I don't know how to change the source code to do that.
By testing, when clicking the header button, items are minimized. The default operation is once click. It works well.
In addition, why did you create UI through code behind? I suggest you could create it through xaml code.
For example:
<StackPanel>
<NavigationView PaneDisplayMode="LeftMinimal" IsPaneOpen="True">
<NavigationView.MenuItems >
<NavigationViewItem Content="Test" Icon="Admin" />
</NavigationView.MenuItems>
</NavigationView>
</StackPanel>
I need to change the source of an Image control inside a gridview datatemplate when a click event is raised in uwp. When i click on a car image, this Image needs to be modified and displayed the brand logo. I succeed with that code:
<controls:AdaptiveGridView x:Name="AdaptiveGridViewControl"
animations:ReorderGridAnimation.Duration="350"
Margin="0,12,0,0"
ItemHeight="200"
DesiredWidth="200"
SelectionMode="Single"
IsItemClickEnabled="True"
ItemClick="GridView_ItemClick"
>
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate x:DataType="data:MyData">
<StackPanel Orientation="Horizontal">
<controls:ImageEx x:Name="ImageExControl"
MaxHeight="200"
IsCacheEnabled="True"
Source="{x:Bind carsPictures}"
Stretch="Fill"
PlaceholderSource="/Assets/placeholder_cover.jpg"
PlaceholderStretch="Uniform"/>
</StackPanel>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
Thanks to that post : How to access a Control inside the data template in C# Metro UI in the code behind,
i can use FindChildControl(DependencyObject control, string ctrlName) method.
In code behind:
private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
var newData = (MyData)e.ClickedItem;
ImageEx ex = FindChildControl<ImageEx>(this, "ImageExControl") as ImageEx;
ex.Source = newData.brandLogo;
}
The problem is this gridview contains 30 cars picture and only the first Image control is modified when a click event is raised. I don't know how to use the AdaptiveGridView.SelectedItem to change the clicked Image control.
You need to Get GridViewItem that has been Clicked so that you can change the image of the Clicked Item. Change your ItemClick Event to something like below.
private void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
GridViewItem item = myGridView.ContainerFromItem(e.ClickedItem) as GridViewItem;
MyData newData = (MyData)e.ClickedItem;
ImageEx ex = FindChildControl<ImageEx>(item, "ImageExControl") as ImageEx;
ex.Source = newData.brandLogo;
}
Hope This Helps.
I have a grid containing an Image (with 2 rows top and bot that I will use later) and another grid containing 4 radio button.
When user click on image, a cross is displayed on the point where he clicked.
There is a part of code :
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0"
x:Name="ImageViewer"
Source="{Binding Picture}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
MouseDown="Image_MouseDown"
MouseMove="ImageViewer_MouseMove"
MouseUp="Image_MouseUp"/>
<local:Cross Grid.Row="0"
CenterPoint="{Binding Point1}"
Foreground="Red"/>
<!-- Grid.Row="1" - Grid with RadioButtons -->
</Grid>
With events :
protected bool StartMove = false;
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
StartMove = true;
Point p = e.GetPosition(ImageViewer);
DrawPoint(p);
}
}
private void Image_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
StartMove = false;
}
}
private void ImageViewer_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && StartMove)
{
Point p = e.GetPosition(ImageViewer);
DrawPoint(p);
}
}
When image is perfectly sized (no border), the cross is correctly drawn. Clicking on my cat eye made this :
But if I resize my window, the cross is moving. I guess that the coordinates are computed considering the white spaces but I don't know how to prevent this.
There it is with the same point :
The cross is drawn by local:Cross element. This element layout is matching to Image and you expect it to draw cross relative to Image.
And it does.
The problem is what Image (disregards it's stretching its size) also stretching its source image. You can try to set Image.Stretch to Fill or solve the problem by using another layout (e.g. Stretch="None", making position and size of Cross and Image equal).
In fact, it is your image that is moving not the cross.
Your problem is that your are catching the position relative to Image UI element, so when you resize your main window you are also resizing your Image element.
Possible solutions:
Fixed size Image element
or, Recalculate the position of your cross when resize
or, Keep your image aligned to top left in your Image
I am working on a UWP project with xaml and c#. I have a stackpanel of images on the right where you can click on the image and it will display a related larger image to the left of the stackpanel.
The large image is set initially to the "large" image that relates to the first "small" image in the stackpanel when you load the page but when you click any of the other small images in the stackpanel, the large image does not update.
The whole thing is a datatemplate that is placed inside a flyout. The relevant xaml for the "large" image is here:
<Border Background="White" Grid.Row="2">
<Image Stretch="Uniform">
<Image.Source>
<BitmapImage UriSource="{Binding SelectedImage}" />
</Image.Source>
</Image>
</Border>
When the small image is clicked, it triggers the "tapped" method for that image and that method is:
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
var img = ((Windows.UI.Xaml.Controls.Image)sender).DataContext as obj
img.FlyoutContent.SelectedImage = new Uri(img.relatedPath);
}
I am using the above code to set the image initially and it works. It just does not change the large image when the small one is clicked.
In debugging, when I click on the small image in the stackpanel, I break at the "image tapped" method and I can see that the uri is getting updated properly and there are no binding errors. The UI never changes.
What am I missing?
Thank you,
Zach
*Side note: the "obj" is just a made up name of a custom class.
For Binding properties you need to implement INotifyPropertyChangedclass so that the UI gets updated automatically.
class CustomClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _imageLink;
public string ImageLink
{
get
{
return _imageLink;
}
set
{
_imageLink = value;
RaisePropertyChanged();
}
}
private void RaisePropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Or as you are using a Tapped event, why not give your XAML element a x:name and set the source of the image of that name to your URi.
To update the ImageLink property, you need to create an instance of the CustomClass in the page you are changing the property.
CustomClass ab = new CustomClass();
ab.ImageLink = "code here";