Transforms on WriteableBitmap - c#

I'm writing app in WP7 mango and try to transform image loaded from binded to WriteableBitmap in XAML for example like this:
<Grid>
<ScrollViewer>
<Image Source="{Binding SourceImage}">
<Image.RenderTransform>
<RotateTransform Angle="{Binding RotateAngle}"/>
</Image.RenderTransform>
</Image>
</ScrollViewer>
</Grid>
I bind Angle with my property Angle in my ViewModel, i change from slider this value but image doesn't rotate. Raising property changed is working correct.
When i do it with image loaded from contets file, static image, it works.

Really weird. I have yet to understand where the problem comes from, but you can get around using Projection instead of RenderTransform:
<Grid>
<ScrollViewer>
<Image Source="{Binding SourceImage}">
<Image.Projection>
<PlaneProjection RotationZ="{Binding RotateAngle}" />
</Image.Projection>
</Image>
</ScrollViewer>
</Grid>
Edit:
Ok, actually it seems the problem comes from the ScrollViewer rather than the Image. Set the RotateTransform directly on the ScrollViewer and it should work:
<Grid>
<ScrollViewer>
<ScrollViewer.RenderTransform>
<RotateTransform Angle="{Binding RotateAngle}" />
</ScrollViewer.RenderTransform>
<Image Source="{Binding SourceImage}" />
</ScrollViewer>
</Grid>
Or put the Image inside a Grid inside the ScrollPanel:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Image Source="{Binding SourceImage}">
<Image.RenderTransform>
<RotateTransform Angle="{Binding RotateAngle}" />
</Image.RenderTransform>
</Image>
</Grid>
</ScrollViewer>
But I'm still clueless about why this happens.
Edit 2:
Ok I found the bug. It has been introduced in the last WP7 builds. Basically, the scrollviewer will overwrite the RenderTransform of its child if it's different than its own.
So you have three solutions:
Define the RenderTransform directly on the ScrollViewer
Wrap your child element in a dummy container element. This way, the dummy element's rendertransform get overwrited and not yours:
At initialization, replace the ScrollViewer's RotateTransform with the element's:
public MainPage()
{
this.InitializeComponent();
this.ScrollViewer.RenderTransform = this.Image.RenderTransform;
}
I would personnaly go with the first or second solution. I fear there could be unexpected side effects with the third solution.

Related

scrollviewer zoom only one element

I have to zoom an image in uwp application, which works fine, but the design requires to have another image (that works as a button) in front of it and I dont want that element to be zoomed as well. It has to be only the image inside the canvas tag, this is how I have it now.
<ScrollViewer MinZoomFactor="1"
ZoomMode="Enabled"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<RelativePanel HorizontalAlignment = "Stretch" >
<Canvas x:Name="canvas">
<Image Source = "{Binding Test,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</Canvas >
<Button RelativePanel.AlignTopWithPanel="True"
Height="55"
Command="{Binding Path=CollapseSplitView}"
CommandParameter="{Binding ElementName=SplitV}">
<Button.Background>
<ImageBrush ImageSource = "/Assets/btlist.png" ></ ImageBrush >
</Button.Background >
</Button >
<Image RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
Source="/Assets/escala-x.png"
Width="130"
Height="70"
Margin="0,0,20,0"
ScrollViewer.IsZoomChainingEnabled="False"
ScrollViewer.IsZoomInertiaEnabled="False">
</Image>
</RelativePanel>
</ScrollViewer>
thats the xaml I have and which makes the zoom work for all elements inside of it. I tried to set scrollViewer.zoomMode=disabled for the elements that are not in the canvas but without luck. Any ideas? Thanks!
I finally fixed it by adding a scrollViewer inside the RelativePanel and then wrap the contents I wanted to zoom inside a StackPanel and then a Grid to be able to have multiple elements inside. Thanks all

ScaleTransform no effect when in DataTemplate

I am using ScaleTransform to change the size of a UserControl on a Canvas. It works perfectly until I use the ItemsControl Control.
The problem is that I need the scaling to be centered, the UserControl should not "move". As soon as it is inside the ItemsControl, the item Scales on Position x=0, y=0 instead of the center.
Would be great to know what I am doing wrong!
Here is some XAML showing it does not work (there is a single item in DataSource, nothing special it only displays a red rectangle on the window).
// This slider is used to scale the Grid inside the ItemsControl.
<Slider x:Name="pointResizeSlider" Margin="10,10,10,0" VerticalAlignment="Top" Maximum="7" Value="1"/>
// The items Control.
<ItemsControl Name="icTest" Background="Blue" Width="200" Height="200">
<ItemsControl.ItemTemplate>
<DataTemplate>
// For simplicity I am using a simple 100x100 Grid. This will get scaled.
<Grid Margin="0 0 5 5" Width="100" Height="100" Background="Red">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform
// This would make it pretty obvious, if it would work.
// Shows no effect.
CenterX="1000"
CenterY="1000"
ScaleX="{Binding Path=Value, ElementName=pointResizeSlider}"
ScaleY="{Binding Path=Value, ElementName=pointResizeSlider}" />
</TransformGroup>
</Grid.LayoutTransform>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Edit
Using RenderTransform works in this case, but I have to calculate the ActualSize of the UserControl (which does not work right now with RenderTransform). Why does LayoutTransform not work in this case?

ViewportControl and Images - how to avoid endless scrolling

I am coding a kind of map (for a very simple game) which is (for now) an image.
I want the user to be able to scroll the image around and resize it.
I tried a lot around, and currently i am using the ViewportControl, and the XAML looks more or less like the following (see below).
I works as it does all i need - BUT the image itself can be scrolled within the ViewportControll without any boundaries. As a result the image scrolls away.
Question: is there any way to prevent the Viewportcontroll to scroll the image out of a specified region?
<ViewportControl x:Name="viewport" Height="600" Width="440">
<Canvas x:Name="ParentCanvas" Background="Red" MaxHeight="600" MaxWidth="440">
<Image x:Name="MapImage" Source="/Artwork/map.png" RenderTransformOrigin="0.2,0.2" Stretch="UniformToFill" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="-200" Canvas.Top="-300" Width="1320" Height="1800">
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
</Image>
<tk:GestureService.GestureListener>
<tk:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</tk:GestureService.GestureListener>
</Canvas>
</ViewportControl>
After testing around i have a solution for my problem.
The most important part is to add the Bounds-tag to the ViewportControl as you can see below.
The scrolling is then handled by the ViewportControl itself. The pinch-gesture must be done manually, but it is possible, because the events will reach the correct UI-Element (here: the image).
In the example below, i used the Windows Phone Toolkit to handle the event more easily.
<ViewportControl x:Name="viewportCtrl" ScrollViewer.VerticalScrollBarVisibility="Visible" VerticalContentAlignment="Center" Bounds="0,0,1320,1800">
<Canvas x:Name="ParentCanvas" Background="Red" Height="1000" Width="800">
<Image x:Name="MapImage" Source="/Artwork/map.png" RenderTransformOrigin="0.2,0.2" >
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
</Image>
<Canvas x:Name="BlueCanvas" Top="100" Left="200" Background="Blue" Height="180" Width="180"></Canvas>
<tk:GestureService.GestureListener>
<tk:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</tk:GestureService.GestureListener>
</Canvas>
</ViewportControl>

Shadow effect and blurry text

I would like to add shadows outside tiles in my WPF application, but when I do, the text inside tiles is blurry. I tried this solution: WPF DropShadowEffect Causing Blurriness , but unfortunately shadow effect seems not to work at all. Are there any special attributtes in Rectangle which should be set? Could you give me some clues?
i got the same issue and solved this by using UseLayoutRounding="True"
EDIT
<Grid UseLayoutRounding="True" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
BlurRadius="20" />
</Grid.Effect>
<!-- your content -->
<Grid Background="White">
<TextBlock Text="Test" FontSize="20" Margin="10" />
</Grid>
</Grid>
results this
hope that helps

Set position of Image programatically in Windows Store App

I am developing a Windows Store application with C# and XAML in which I have an image being displayed on user screen. On certain event I want to change its position on screen to the coordinates of my choice.
I have tried
Canvas.SetLeft(selectedImage, screenCoords.X);
Canvas.SetTop(selectedImage, screenCoords.Y);
and
selectedImage.SetValue(Canvas.LeftProperty, screenCoords.X);
selectedImage.SetValue(Canvas.TopProperty, screenCoords.Y);
But they are not working. I have also tried updating the layout after this. can anyone tell me what exactly am I doing wrong here?
Here is the XAML code:
<FlipView.ItemTemplate>
<DataTemplate>
<Grid x:Name="cv">
<Image x:Name="img1" Source = "{Binding ModelImage}" Stretch="Fill" Tag="{Binding ModelTag}" Tapped="ModelTapped"/>
<Image x:Name="hat" Source = "{Binding HatImage}" Width="{Binding HatWidth, Mode=TwoWay}" Height="{Binding HatHeight, Mode=TwoWay}" Stretch="Fill" ManipulationMode="All" ManipulationDelta="ResourceImage_ManipulationDelta" Tapped="imageTapped" Tag="{Binding hatTag}" Canvas.ZIndex="3">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
I have several images in the grid named 'cv', just removed them for simplicity. selectedImage in above C# code is one of the images in the grid 'cv'.
I solved the issue by translating my image to the desired points using RenderTransform property.

Categories