Reputation: 35
I have a canvas which has many images appearing dynamically on it and i used items control for it. I had to drag drop and rotate(on mouse right button click) those images and update new locations and rotation angle back to source code (VM and Model).
I am able to display on my screen images and my canvas.left and canvas.right are getting updated for new locations in source when i do drag and drop of Images on canvas. The problem is when i rotate image, The image gets rotated but the new Angle in source is not updated in my source (VModel), I mean this property never gets called when i rotate the image.
public double Angle {
get { return angle; }
set //NEVER GETS CALLED ON ROTATION
{
angle = value;
RaisePropertyChanged("Angle");
}
}
It is binded correctly because when i display the images dynamically on canvas, they are displayed with the same angle which i have provided them from source. Earlier i suspected Mode to not set of TwoWay binding. Even i set to TwoWay it do not work. I also added UpdateSourceTrigger=PropertyChanged but still do not work . Why angle is never updated on rotating the image whereas canvas.left and canvas.top are updated.
Here is my XAML :
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<dd:DragCanvas Height="800" Width="1000" Background="Black" x:Name="dragCanvas"
AllowDragging="True"
/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=path}" >
</Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=Canvas_Left , Mode=TwoWay}" /> //It is updated
<Setter Property="Canvas.Top" Value="{Binding Path=Canvas_Top , Mode=TwoWay}" /> //It is Updated
<Setter Property="RenderTransform"> //It never updated from target to source but source to target is updated
<Setter.Value>
<RotateTransform Angle="{Binding Path=Angle ,Mode=TwoWay}"/>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Here is where i rotate on mouse right button click(inside dd:DragCanvas )
public class DragCanvas : Canvas
{
protected override void OnMouseRightButtonUp(MouseButtonEventArgs e) //HERE IS WHERE I ROTATE by 90 degree
{
base.OnMouseRightButtonUp(e);
ElementBeingDragged = e.Source as UIElement;
var rotateTransform = ElementBeingDragged.RenderTransform as RotateTransform;
if (rotateTransform == null)
{
rotateTransform = new RotateTransform();
ElementBeingDragged.RenderTransform = rotateTransform;
ElementBeingDragged.RenderTransformOrigin = new Point(0.5, 0.5);
}
rotateTransform.Angle += 90;
ElementBeingDragged.UpdateLayout();
}
}
How to update angle property (target to source), such that each time i rotate the Image i have set part of the property Angle called
public double Angle {
get { return angle; }
set //It must be called when i rotate the image on right mouse click
{
angle = value;
RaisePropertyChanged("Angle");
}
}
Upvotes: 1
Views: 284
Reputation: 132548
You're binding to LayoutTransform
but updating RenderTransform
. LayoutTransform
gets applied while calculating Layout, while RenderTransform
gets applied at the time of rendering.
Change your binding to RenderTransform
and it should work.
Edit : Just realized when switching to using RenderTransform
, you need to apply the transform to the Image, not the ContentPresenter
wrapping the image.
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=path}" >
<Image.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="{Binding Path=Angle ,Mode=TwoWay}"/>
</Setter.Value>
</Setter>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=Canvas_Left , Mode=TwoWay}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Canvas_Top , Mode=TwoWay}" />
</Style>
</ItemsControl.ItemContainerStyle>
If you apply a transformation during the Layout pass, it will adjust other items within the Layout to fit as well. So applying a transform to the ContentPresenter
that wraps the Image
during Layout will also calculate that it needs to apply the same transform to the inside Image
.
But if it's applied during Rendering, the only the ContentPresenter
gets the transform applied and the child Image
remains unchanged because the initial Layout pass decided it didn't need any modifications.
Upvotes: 1