Ich habe an einer Windows 8.1 RT-App gearbeitet, bei der der Benutzer ein Bild mit Stretch = Uniform lädt. Das Bild kann so klein wie möglich und so groß wie möglich sein. Die Beschneidung geschieht in meiner Benutzersteuerung und meine Benutzerkontrolle erscheint, wenn ich auf den Bildschirm/das Bild tippe/drücke und halte. Clipping passiert, wenn ich tippe und halte und meine Finger/Maus um das Bild im Hintergrund bewege.Ein Bild mit niedriger Auflösung mit Transforms schneiden und es meinem Benutzersteuerelement zuweisen
Die Probleme Ich bin vor sind
Jedes Mal, wenn die App zum ersten Mal auf Emulator, und zum ersten Mal geladen wird, wenn der Hahn/Klicks und Haltedurchgeführt wird, wird der Benutzer die Kontrolle über oben links auf dem Bildschirm und dann über meinem angeklickten/gehaltenen Bereich. Was ich benötige, ist, dass es immer dort erscheint, wo ich klicke und halte und wenn ich klicke und halte. Beim Loslassen des Fingers/der Maus sollte es zusammenbrechen.
Ich benutze Zentrum transformieren. Ich möchte die Region (das Pixel), wo meine Maus derzeit genau in der Mitte des Benutzersteuerelements angezeigt wird, Wenn ich ein Bild mit kleiner Auflösung 480 * 800 oder noch kleiner laden, kommt der Bereich meiner Maus nicht in die Mitte. Um klarer zu sein, stellen Sie sich vor, ich klopfe und halte an der CORNEA des menschlichen Auges. Die Hornhaut sollte in der Mitte der Benutzersteuerung angezeigt werden und der Bereich über und unter sollte den Rest des Teils abdecken.
- Ich möchte nicht, dass meine Steuerung außerhalb meiner Bildgrenze liegt. Wenn meine Maus auf dem letzten Pixel des Bildes ist, sollte ein Teil des Bildes und ein Teil des Hintergrunds sein angezeigt.
Ich muss die Kontrolle drehen, wie in der unten video finden den vollständigen Code gezeigt.
MainPage.xaml
<Page
x:Class="App78.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App78"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
x:Name="LayoutGrid"
Margin="0,0"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Holding="LayoutGrid_Holding"
PointerMoved="LayoutGrid_OnPointerMoved"
PointerWheelChanged="LayoutGrid_OnPointerWheelChanged"
PointerPressed="LayoutGrid_OnPointerPressed"
PointerReleased="LayoutGrid_OnPointerReleased">
<Image
x:Name="BigImage"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Source="http://blog.al.com/space-news/2009/04/iss015e22574.jpg" />
<local:Magnifier VerticalAlignment="Top" HorizontalAlignment="Left" x:Name="MagnifierTip" Visibility="Collapsed" />
</Grid>
</Page>
MainPage.xaml.cs
using System;
using System.Diagnostics;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
namespace App78
{
public sealed partial class MainPage : Page
{
private double zoomScale = 2;
private double pointerX = 0;
private double pointerY = 0;
private const double MinZoomScale = .25;
private const double MaxZoomScale = 32;
public MainPage()
{
this.InitializeComponent();
var bi = (BitmapImage)BigImage.Source;
bi.ImageOpened += bi_ImageOpened;
this.SizeChanged += MainPage_SizeChanged;
}
void MainPage_SizeChanged(object sender, Windows.UI.Xaml.SizeChangedEventArgs e)
{
this.UpdateImageLayout();
}
void bi_ImageOpened(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
this.UpdateImageLayout();
}
private void UpdateImageLayout()
{
var bi = (BitmapImage)BigImage.Source;
if (bi.PixelWidth < this.LayoutGrid.ActualWidth &&
bi.PixelHeight < this.LayoutGrid.ActualHeight)
{
this.BigImage.Stretch = Stretch.None;
}
else
{
this.BigImage.Stretch = Stretch.Uniform;
}
this.UpdateMagnifier();
}
private void LayoutGrid_OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
//DV: If pointer is not in contact we can ignore it
if (!e.Pointer.IsInContact) { return; }
var point = e.GetCurrentPoint(this.LayoutGrid);
this.pointerX = point.Position.X;
this.pointerY = point.Position.Y;
this.UpdateMagnifier();
}
private void UpdateMagnifier()
{
var bi = (BitmapImage)BigImage.Source;
double offsetX = 0;
double offsetY = 0;
double imageScale = 1;
var imageRatio = (double)bi.PixelWidth/bi.PixelHeight;
var gridRatio = this.LayoutGrid.ActualWidth/this.LayoutGrid.ActualHeight;
if (bi.PixelWidth < this.LayoutGrid.ActualWidth &&
bi.PixelHeight < this.LayoutGrid.ActualHeight)
{
offsetX = 0.5 * (this.LayoutGrid.ActualWidth - bi.PixelWidth);
offsetY = 0.5 * (this.LayoutGrid.ActualHeight - bi.PixelHeight);
//imageScale = 1; - remains
}
else if (imageRatio < gridRatio)
{
offsetX = 0.5 * (this.LayoutGrid.ActualWidth - imageRatio * this.LayoutGrid.ActualHeight);
offsetY = 0;
imageScale = BigImage.ActualHeight/bi.PixelHeight;
}
else
{
offsetX = 0;
offsetY = 0.5 * (this.LayoutGrid.ActualHeight - this.LayoutGrid.ActualWidth/imageRatio);
imageScale = BigImage.ActualWidth/bi.PixelWidth;
}
//DV: This is probably not need anymore
//MagnifierTip.MagnifierTransform.X = this.pointerX;
//MagnifierTip.MagnifierTransform.Y = this.pointerY;
MagnifierTip.PositionTransform.X = (-this.pointerX + offsetX)/imageScale;
MagnifierTip.PositionTransform.Y = (-this.pointerY + offsetY)/imageScale;
//DV: I haven't tested the Scaling/Zoom
MagnifierTip.ZoomTransform.ScaleX = imageScale * zoomScale;
MagnifierTip.ZoomTransform.ScaleY = imageScale * zoomScale;
MagnifierTip.CenterTransform.X = MagnifierTip.MagnifierEllipse.ActualWidth/2 - MagnifierTip.MagnifierEllipse.StrokeThickness/2;
MagnifierTip.CenterTransform.Y = MagnifierTip.MagnifierEllipse.ActualHeight/2 - MagnifierTip.MagnifierEllipse.StrokeThickness/2;
//DV: I added a GlobalGrid Transform which translates every children
MagnifierTip.MagnifierTransformGrid.X = this.pointerX - (MagnifierTip.ActualWidth/2);
MagnifierTip.MagnifierTransformGrid.Y = this.pointerY - (MagnifierTip.ActualHeight); ;
}
private void LayoutGrid_OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
if (e.GetCurrentPoint(this.LayoutGrid).Properties.MouseWheelDelta > 0)
{
zoomScale = Math.Max(MinZoomScale, Math.Min(MaxZoomScale, zoomScale * 1.2));
}
else
{
zoomScale = Math.Max(MinZoomScale, Math.Min(MaxZoomScale, zoomScale/1.2));
}
this.UpdateMagnifier();
}
//DV: Holding usually only works with touch https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.uielement.holding.aspx?f=255&MSPPError=-2147217396
private void LayoutGrid_Holding(object sender, HoldingRoutedEventArgs e)
{
//
}
//DV: pointer pressed supports both mouse and touch but fires immeadiatley. You'll have to figure out a delay strategy or using holding for touch and right click for mouse
private void LayoutGrid_OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
MagnifierTip.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
//DV: pointer released supports both mouse and touch.
private void LayoutGrid_OnPointerReleased(object sender, PointerRoutedEventArgs e)
{
MagnifierTip.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
}
}
Magnifier.XAML
<UserControl
x:Class="App78.Magnifier"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App78"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Height="230"
Width="170">
<Grid Height="230" Width="170">
<!-- DV: This is the global transform I added -->
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="MagnifierTransformGrid" x:FieldModifier="public"/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse Opacity="1" Visibility="Visible" Fill="{ThemeResource ApplicationPageBackgroundThemeBrush}" HorizontalAlignment="Center" VerticalAlignment="Top" IsHitTestVisible="False" Width="135" Height="128" StrokeThickness="3" Margin="0,17,0,0" />
<Ellipse x:Name="MagnifierEllipse" x:FieldModifier="public" Opacity="1" Visibility="Visible" HorizontalAlignment="Left" VerticalAlignment="Top" IsHitTestVisible="False" Width="150" Height="150" Stroke="White" StrokeThickness="3" Margin="11,8,0,0" >
<Ellipse.Fill>
<ImageBrush
ImageSource="http://blog.al.com/space-news/2009/04/iss015e22574.jpg"
Stretch="None"
AlignmentX="Left"
AlignmentY="Top">
<ImageBrush.Transform>
<TransformGroup>
<TranslateTransform x:FieldModifier="public"
x:Name="CenterTransform"/>
<TranslateTransform x:FieldModifier="public"
x:Name="PositionTransform"/>
<ScaleTransform x:FieldModifier="public"
x:Name="ZoomTransform"/>
</TransformGroup>
</ImageBrush.Transform>
</ImageBrush>
</Ellipse.Fill>
</Ellipse>
<Path Data="M25.533,0C15.457,0,7.262,8.199,7.262,18.271c0,9.461,13.676,19.698,17.63,32.338 c0.085,0.273,0.34,0.459,0.626,0.457c0.287-0.004,0.538-0.192,0.619-0.467c3.836-12.951,17.666-22.856,17.667-32.33 C43.803,8.199,35.607,0,25.533,0z M25.533,32.131c-7.9,0-14.328-6.429-14.328-14.328c0-7.9,6.428-14.328,14.328-14.328 c7.898,0,14.327,6.428,14.327,14.328C39.86,25.702,33.431,32.131,25.533,32.131z"
Fill="#FFF4F4F5"
Stretch="Fill"
Stroke="Black"
UseLayoutRounding="False"
Height="227"
Width="171" ></Path>
</Grid>
</UserControl>
Der Einfachheit halber kann das Projekt von here heruntergeladen werden. Zum besseren Verständnis möchte ich, dass Sie dieses video sehen. Genau das muss ich implementieren.
tut die Antwort, die ich Ihre pr gab lösen Problem? – Neeraj
@Neeraj Bro Ich bin es noch zu überprüfen! Ich werde es überprüfen und zu dir zurückkommen! Die Frage besteht aus mehreren Teilen und ich brauche Antworten von allen! – Apoorv
Ich denke, diese sollten Sie über die Buckel in der Umsetzung für alle drei Teile nehmen :) !! . – Neeraj