Use Binding to connect Ellipses with a Line - c#

I use the following Bindings to connect two Ellipses with a line:
Line l = new Line();
l.Stroke = Brushes.Green;
l.StrokeThickness = 3;
Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
x1.Source = y1.Source = e;
x2.Source = y2.Source = e1;
l.SetBinding(Line.X1Property, x1);
l.SetBinding(Line.Y1Property, y1);
l.SetBinding(Line.X2Property, x2);
l.SetBinding(Line.Y2Property, y2);
Dependencies.Children.Add(l);
This works great, but the problem is, the lines are drawn on the left top of the Ellipse. I'd like to use the center of the Ellipse. Therefore I would have to add Ellipse#width / 2 to the x property. But how can I do that?

You can use IValueConverter to change/transform values while Binding.
Here is something I cooked up:
Canvas Dependencies = new Canvas();
Ellipse e1 = new Ellipse() { Width = 200, Height = 200, Stroke = Brushes.Red, StrokeThickness = 1 };
Ellipse e2 = new Ellipse() { Width = 200, Height = 200, Stroke = Brushes.Red, StrokeThickness = 1 };
Line l = new Line();
l.Stroke = Brushes.Green;
l.StrokeThickness = 3;
Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty); x1.Converter = new MyConverter(); x1.ConverterParameter = e1;
Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty); y1.Converter = new MyConverter(); y1.ConverterParameter = e1;
Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty); x2.Converter = new MyConverter(); x2.ConverterParameter = e2;
Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty); y2.Converter = new MyConverter(); y2.ConverterParameter = e2;
x1.Source = y1.Source = e1;
x2.Source = y2.Source = e2;
l.SetBinding(Line.X1Property, x1);
l.SetBinding(Line.Y1Property, y1);
l.SetBinding(Line.X2Property, x2);
l.SetBinding(Line.Y2Property, y2);
Dependencies.Children.Add(e1);
Dependencies.Children.Add(e2);
Dependencies.Children.Add(l);
SizeChangedEventHandler act = (Object s, SizeChangedEventArgs args) =>
{
BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
};
e1.SizeChanged += act;
e2.SizeChanged += act;
Canvas.SetLeft(e1, 200);
Canvas.SetTop(e1, 200);
Canvas.SetLeft(e2, 500);
Canvas.SetTop(e2, 500);
Grid2.Children.Add(Dependencies);
Converter:
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Ellipse e = parameter as Ellipse;
Double d = (Double)value;
return d + (e.ActualWidth / 2);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Ellipse e = parameter as Ellipse;
Double d = (Double)value;
return d - (e.ActualWidth / 2);
}
}
Note that the converter considers Ellipse.Width only. You will need to modify it to make it work correctly.

Your binding now depends on two properties, the Canvas.Left (or Canvas.Top), and the Ellipse.ActualWidth (or height). To achieve this you can use a multibinding. See the following examples:
http://www.switchonthecode.com/tutorials/wpf-tutorial-using-multibindings
However, there are other, possibly simpler alternatives. You could use a render transform to translate your ellipses by an X position which is half of its width and a Y position that is half of its height, to centre your ellipse at the position given by Canvas.Left and canvas.Top
Regards, Colin E.

Related

WPF Ellipse wont resize correctly on MouseEnter Event

I am using ChartView Telerik WPF Library. I want the points to get bigger when the user hovers over them. But for some reason it is not working as expected. The Ellipse gets bigger but it does not resize correctly. But I don't understand why. The other properties as border color and thickness are working correctly.
Can someone tell me what am I missing here ?
This is how it looks currently when I try to resize the point :
Here is the Source Code:
private FrameworkElementFactory AddPointsToSeries(KeyValuePair<ChartSerie, List<ChartDataPoint>> chartSeries, int colorPaletteIndex)
{
var seriesPredefinedColor = this.ChartBase.Palette.GlobalEntries[colorPaletteIndex].Fill;
FrameworkElementFactory frameworkElement = new FrameworkElementFactory(typeof(Ellipse));
frameworkElement.SetValue(Ellipse.FillProperty, ColorService.BrushFromHex(chartSeries.Key.ColorHex) ?? seriesPredefinedColor);
frameworkElement.SetValue(Ellipse.HeightProperty, 9.0D);
frameworkElement.SetValue(Ellipse.WidthProperty, 9.0D);
frameworkElement.AddHandler(Ellipse.MouseEnterEvent, new MouseEventHandler((sender, args) =>
{
Ellipse ellipse = (Ellipse)sender;
ellipse.Stroke = ColorService.BrushFromHex(ColorService.BlendHex((chartSeries.Key.ColorHex ?? ColorService.BrushToHex(seriesPredefinedColor)), "#000000", 0.4));
// this is not correctly applied!
ellipse.Width = 15;
ellipse.Height = 15;
ellipse.StrokeThickness = 2;
}));
frameworkElement.AddHandler(Ellipse.MouseLeaveEvent, new MouseEventHandler((sender, args) =>
{
Ellipse ellipse = (Ellipse)sender;
ellipse.Height = 8;
ellipse.Width = 8;
ellipse.Stroke = null;
}));
return frameworkElement;
}
// Here I create the Line Series and here I use the AddPointsToSeries Method
private LineSeries CreateLineSeries(KeyValuePair<ChartSerie, List<ChartDataPoint>> chartSeries, ChartLegendSettings legendSettings,
int colorPaletteIndex)
{
FrameworkElementFactory addPoints = AddPointsToSeries(chartSeries, colorPaletteIndex);
var lineSerie = new LineSeries()
{
VerticalAxis = CreateMultipleVerticalAxis(chartSeries, colorPaletteIndex, out var multipleVerticalAxis) ? multipleVerticalAxis : null,
ZIndex = 150, // the line series should always be displayed on top of other series.
StrokeThickness = 3.5,
LegendSettings = (SeriesLegendSettings)legendSettings,
Opacity = 0.8,
StackGroupKey = chartSeries.Key.Group,
CombineMode = string.IsNullOrEmpty(chartSeries.Key.Group) ? ChartSeriesCombineMode.None : ChartSeriesCombineMode.Stack,
PointTemplate = new DataTemplate()
{
VisualTree = addPoints,
},
};
// this is the color of line series
if (chartSeries.Key.ColorHex != null)
{
lineSerie.Stroke = (SolidColorBrush)(new BrushConverter().ConvertFrom(chartSeries.Key.ColorHex));
}
foreach (ChartDataPoint serie in chartSeries.Value)
{
lineSerie.DataPoints.Add(new CategoricalDataPoint()
{
Category = serie.XPoint.Label,
Value = (double?)serie.Value,
});
}
return lineSerie;
}
My question was answered my Martin Ivanov:
This behavior comes from the size caching mechanism of the chart. Basically, the control is setting the size of the visual when initially loaded and then it doesn't change it unless something on the chart's API changes. In order to achieve your requirement you can wrap the ellipse in a Grid panel and its Width and Height properties to be the same (or little bigger) then the size of the bigger ellipse.
This is the solution:
private FrameworkElementFactory AddPointsToSeries(KeyValuePair<ChartSerie, List<ChartDataPoint>> chartSeries, int colorPaletteIndex)
{
var seriesPredefinedColor = this.ChartBase.Palette.GlobalEntries[colorPaletteIndex].Fill;
Brush brush = chartSeries.Key.ColorHex == null ? (seriesPredefinedColor) : ColorService.HexToBrush(chartSeries.Key.ColorHex);
Brush mouseOnEnterColor = new SolidColorBrush(ColorService.ChangeColorLightness(ColorService.BrushToColor(brush), 0.8));
double ellipseMouseOverStrokeThickness = 2;
double ellipseMouseOverHeightWidth = 13;
double ellipseStrokeThickness = 1;
double ellipseHeightWidth = 9;
FrameworkElementFactory frameworkElement = new FrameworkElementFactory(typeof(Ellipse));
frameworkElement.SetValue(Ellipse.FillProperty, brush);
frameworkElement.SetValue(Ellipse.MarginProperty, new Thickness(-4.5));
frameworkElement.SetValue(Ellipse.HeightProperty, ellipseHeightWidth);
frameworkElement.SetValue(Ellipse.WidthProperty, ellipseHeightWidth);
frameworkElement.SetValue(Ellipse.StrokeProperty, new SolidColorBrush(Colors.White));
frameworkElement.SetValue(Ellipse.StrokeThicknessProperty, ellipseStrokeThickness);
frameworkElement.AddHandler(Ellipse.MouseEnterEvent, new MouseEventHandler((sender, args) =>
{
Ellipse ellipse = (Ellipse)sender;
ellipse.Fill = new SolidColorBrush(Colors.White);
ellipse.Stroke = mouseOnEnterColor;
ellipse.StrokeThickness = ellipseMouseOverStrokeThickness;
ellipse.Width = ellipseMouseOverHeightWidth;
ellipse.Height = ellipseMouseOverHeightWidth;
}));
frameworkElement.AddHandler(Ellipse.MouseLeaveEvent, new MouseEventHandler((sender, args) =>
{
Ellipse ellipse = (Ellipse)sender;
ellipse.Stroke = new SolidColorBrush(Colors.White);
ellipse.Fill = brush;
ellipse.StrokeThickness = ellipseStrokeThickness;
ellipse.Height = ellipseHeightWidth;
ellipse.Width = ellipseHeightWidth;
}));
FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(Grid));
stackPanelFactory.SetValue(Grid.HeightProperty, ellipseMouseOverHeightWidth + ellipseMouseOverStrokeThickness);
stackPanelFactory.SetValue(Grid.WidthProperty, ellipseMouseOverHeightWidth + ellipseMouseOverStrokeThickness);
stackPanelFactory.AppendChild(frameworkElement);
return stackPanelFactory;
}
Now it looks like this:

Binding WPF Extended Toolkit ColorPicker SelectedColor Property to DependencyProperty

I'm trying to bind the SelectedColor property of the WPF Extended Toolkit ColorPicker to a DependencyProperty with type SolidColorBrush. This color is then supposed to be used as the Fill color of a Shape sitting on/in a Canvas.
This isn't working, and as I understand it, the problem is that the SelectedColor property of the ColorPicker is actually an object with type Color?. My question is, how do I get this to work? If I just do it in code through a method hooked up to an event, I can use SelectedColor.Value, but AFAIK that isn't as option in XAML.
I did try to use a regular property and have the class inherit from INotifyPropertyChanged (as in SelectedColor binding doesn't update from ColorPicker to Model), rather than from DependencyObject, but that didn't work either.
I'd prefer to do this with Binding, as I'm trying to get more in the practice of using MVVM. I've only recently learned how to use MVVM, and I actually prefer it now, so I'd really like avoid just using code-behind.
XAML:
<toolkit:ColorPicker x:Name="fillColor" Grid.Column="1" Grid.Row="8" Margin="5" VerticalAlignment="Top" SelectedColor="{Binding Path=FillColor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedColorChanged="fillColor_SelectedColorChanged" />
<toolkit:ColorPicker x:Name="lineColor" Grid.Column="2" Grid.Row="8" Margin="5" VerticalAlignment="Top" />
C#:
private static DependencyProperty FillColorProperty = DependencyProperty.Register("FillColor", typeof(SolidColorBrush),
typeof(TuckboxModel), new FrameworkPropertyMetadata(Brushes.Purple));
private static DependencyProperty LineColorProperty = DependencyProperty.Register("LineColor", typeof(SolidColorBrush),
typeof(TuckboxModel), new FrameworkPropertyMetadata(Brushes.Black));
public SolidColorBrush FillColor
{
get { return (SolidColorBrush)GetValue(FillColorProperty); }
set
{
SetValue(FillColorProperty, value);
}
}
public SolidColorBrush LineColor
{
get { return (SolidColorBrush)GetValue(LineColorProperty); }
set { SetValue(LineColorProperty, value); }
}
public void CreateBox(Canvas drawingCanvas, TuckboxModel model, double width, double height, double depth, SolidColorBrush shading, SolidColorBrush outline)
{
double xOrigin = 50;
double yOrigin = 450;
double xCoord = xOrigin;
double yCoord = yOrigin;
Shape item;
double flapSize;
long count;
//Remove all previous shapes from Canvas
drawingCanvas.Children.Clear();
Path border = new Path();
border.Stroke = model.LineColor;
border.StrokeThickness = 1.0;
border.Fill = model.FillColor;
//border.Fill = shading;
yCoord -= ToPts(depth);
xCoord += ToPts(depth);
RectangleGeometry rectangleA = new RectangleGeometry();
Rect rectA = new Rect(xCoord, yCoord, ToPts(width), ToPts(depth));
rectangleA.Rect = rectA;
xCoord += ToPts(width);
RectangleGeometry rectangleB = new RectangleGeometry();
Rect rectB = new Rect(xCoord + 3, yCoord, ToPts(depth) - 5, ToPts(depth));
rectangleB.Rect = rectB;
xCoord += ToPts(depth);
RectangleGeometry rectangleC = new RectangleGeometry();
Rect rectC = new Rect(xCoord + 2, yCoord, ToPts(width) - 4, ToPts(depth) - 2);
rectangleC.Rect = rectC;
xCoord += ToPts(width);
RectangleGeometry rectangleD = new RectangleGeometry();
Rect rectD = new Rect(xCoord + 2, yCoord, ToPts(depth) - 5, ToPts(depth));
rectangleD.Rect = rectD;
xCoord = xOrigin;
yCoord -= ToPts(height);
RectangleGeometry rectangleE = new RectangleGeometry();
Rect rectE = new Rect(xCoord, yCoord, ToPts(depth), ToPts(height));
rectangleE.Rect = rectE;
xCoord += ToPts(depth);
RectangleGeometry rectangleF = new RectangleGeometry();
Rect rectF = new Rect(xCoord, yCoord, ToPts(width), ToPts(height));
rectangleF.Rect = rectF;
xCoord += ToPts(width);
RectangleGeometry rectangleG = new RectangleGeometry();
Rect rectG = new Rect(xCoord, yCoord, ToPts(depth), ToPts(height));
rectangleG.Rect = rectG;
xCoord += ToPts(depth);
RectangleGeometry rectangleH = new RectangleGeometry();
Rect rectH = new Rect(xCoord, yCoord, ToPts(width), ToPts(height));
rectangleH.Rect = rectH;
xCoord += ToPts(width);
RectangleGeometry rectangleI = new RectangleGeometry();
Rect rectI = new Rect(xCoord, yCoord, ToPts(depth) - 3, ToPts(height));
rectangleI.Rect = rectI;
xCoord = xOrigin;
yCoord -= ToPts(depth);
RectangleGeometry rectangleJ = new RectangleGeometry();
Rect rectJ = new Rect(xCoord + 1, yCoord, ToPts(depth) - 2, ToPts(depth));
rectangleJ.Rect = rectJ;
xCoord += ToPts(depth);
RectangleGeometry rectangleK = new RectangleGeometry();
Rect rectK = new Rect(xCoord, yCoord, ToPts(width), ToPts(depth));
rectangleK.Rect = rectK;
xCoord += ToPts(width);
RectangleGeometry rectangleL = new RectangleGeometry();
Rect rectL = new Rect(xCoord + 1, yCoord, ToPts(depth) - 2, ToPts(depth));
rectangleL.Rect = rectL;
EllipseGeometry ellipseA = new EllipseGeometry();
ellipseA.Center = new Point(rectK.Right - (rectK.Width / 2), yCoord);
ellipseA.RadiusX = rectK.Width / 2;
if(height < 1.0)
flapSize = ToPts(height);
else
flapSize = 72;
ellipseA.RadiusY = flapSize;
GeometryGroup finalShape = new GeometryGroup();
finalShape.Children.Add(rectangleA);
finalShape.Children.Add(rectangleB);
finalShape.Children.Add(rectangleC);
finalShape.Children.Add(rectangleD);
finalShape.Children.Add(rectangleE);
finalShape.Children.Add(rectangleF);
finalShape.Children.Add(rectangleG);
finalShape.Children.Add(rectangleH);
finalShape.Children.Add(rectangleI);
finalShape.Children.Add(rectangleJ);
finalShape.Children.Add(rectangleK);
finalShape.Children.Add(rectangleL);
finalShape.Children.Add(ellipseA);
finalShape.FillRule = FillRule.Nonzero;
border.Data = finalShape;
drawingCanvas.Children.Add(border);
}
Any help will be greatly appreciated!
I think a Converter is an answer for your troubles. Here is an example of a converter class:
using System;
using System.Globalization;
using System.Windows.Data;
namespace SO_app.Converters
{
public class DebugConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (null == value) {
return null;
}
// For a more sophisticated converter, check also the targetType and react accordingly..
if (value is Color) {
Color color = (Color)value;
return new SolidColorBrush(color);
}
// You can support here more source types if you wish
// For the example I throw an exception
Type type = value.GetType();
throw new InvalidOperationException("Unsupported type ["+type.Name+"]");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}
And then in your xaml it would look like this:
This is for my project:
xmlns:converter="clr-namespace:SO_app.Converters"
Then in resources:
<converter:DebugConverter x:Key="DebugConverter"/>
Then in xaml:
<toolkit:ColorPicker x:Name="fillColor" Grid.Column="1" Grid.Row="8" Margin="5" VerticalAlignment="Top" SelectedColor="{Binding Path=FillColor, Converter={StaticResource DebugConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedColorChanged="fillColor_SelectedColorChanged" />
Note:
The code for conversion of types is from this SO post.
UPDATE:
Check this SO post which means that there is a built in converter in toolkit

Line with its length self-adjusting to parent-Panel's ActualWidth property (data-binding)

I have a vertical StackPanel and I want it to contain Line-child with .X2 value binded to parent-StackPanel's ActualWidth. Something like:
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Vertical;
(...)
Line line = new Line();
line.X1 = 0;
line.X2 = <Some binding to sp.ActualWidth>;
// line.Y1 = line.Y2 - will it set it's value to 0 by default?
line.StrokeThickness = 2;
(...)
sp.Children.Add(line);
Should I use INotifyPropertyChanged interface? Is this the most proper way?
INotifyPropertyChanged is not necessary.
Just create a binding and setbinding to X2Property of the line.
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Vertical;
Line line = new Line();
line.X1 = 0;
var bind = new Binding()
{
Source = sp,
Path = new PropertyPath("ActualWidth")
};
BindingOperations.SetBinding(line, Line.X2Property, bind);
line.StrokeThickness = 2;
line.Stroke=Brushes.Black;
line.Margin=new Thickness(10);
sp.Children.Add(line);
An alternative to a Line with a bound X2 property and a StrokeThickness of 2 would be a Rectangle with a Height of 2. Its width is automatically set to the StackPanel width.
var sp = new StackPanel
{
Orientation = Orientation.Vertical
};
...
var line = new Rectangle
{
Height = 2,
Fill = Brushes.Black
};
sp.Children.Add(line);

Blurry Transformed Text in WPF

I'm using DrawingContext.DrawText and DrawingContext.PushTransfrom to create rotated text on Visual Layer in WPF but as you see in the image below, the rotated text is rather blurry in some areas of the image..
Is there any option I can use to improve this? The Arial font is used for the text.
public class BeamTextDrawing : FrameworkElement
{
private readonly VisualCollection _visuals;
public BeamTextDrawing(double scale)
{
if (scale <= 0)
{
scale = 1;
}
var typeface = Settings.BeamTextTypeface;
var cultureinfo = Settings.CultureInfo;
var flowdirection = Settings.FlowDirection;
var textsize = Settings.BeamTextSize / scale;
var beamtextcolor = Settings.InPlanBeamTextColor;
_visuals = new VisualCollection(this);
foreach (var beam in Building.BeamsInTheElevation)
{
var drawingVisual = new DrawingVisual();
using (var dc = drawingVisual.RenderOpen())
{
var text = Convert.ToString(beam.Section.Id);
//text = scale.ToString();
var ft = new FormattedText(text, cultureinfo, flowdirection,
typeface, textsize, beamtextcolor)
{
TextAlignment = TextAlignment.Center
};
var x1 = beam.ConnectivityLine.I.X;
var y1 = beam.ConnectivityLine.I.Y;
var x2 = beam.ConnectivityLine.J.X;
var y2 = beam.ConnectivityLine.J.Y;
var v1 = new Point(x2, y2) - new Point(x1, y1);
var v2 = new Vector(1, 0);
var hwidth = textsize;
var l = Geometrics.GetOffset(x1, y1, x2, y2, hwidth + 5/scale);
var angle = Vector.AngleBetween(v1, v2);
var x = 0.5 * (l.X1 + l.X2);
var y = 0.5 * (l.Y1 + l.Y2);
var r = new RotateTransform(angle, x, SelectableModel.FlipYAxis(y));
dc.PushTransform(r);
dc.DrawText(ft, SelectableModel.FlipYAxis(x, y));
}
_visuals.Add(drawingVisual);
}
}
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}
}
Update:
Here is the image after using this code:
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
I'm still getting blurry results. Look at the middle beam text at the lower part of the image.
You can change the TextFormattingMode to prevent blurry text:
public BeamTextDrawing(double scale)
{
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
// .. Your other code

Bind AngleProperty of the image in code

UPDATE
I want to add an image to my canvas programmatically. I want to bind X, Y coords and Angle of the Image. X and Y binding works fine, but the Angle doesn't. Here is the code:
public void AddNewImage()
{
Image newImage = new Image
{
Source = new BitmapImage(new Uri(imagePath))
};
These two work fine
Binding binding1 = new Binding("X");
binding1.Mode = BindingMode.TwoWay;
binding1.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(newImage, Canvas.LeftProperty, binding1);
Binding binding2 = new Binding("Y");
binding2.Mode = BindingMode.TwoWay;
binding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(newImage, Canvas.TopProperty, binding2);
That's why I use a group
TransformGroup tg = new TransformGroup();
tg.Children.Add(new TranslateTransform(xTranslate,yTranslate));
tg.Children.Add(new RotateTransform());
newImage.RenderTransform = tg;
This one doesn't work
Binding binding3 = new Binding("Angle");
binding3.Mode = BindingMode.TwoWay;
binding3.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(tg, RotateTransform.AngleProperty, binding3);
MainCanvas.Children.Add(newImage);
}
When I change X and Y - image moves, but when I change angle - nothing happens.
What do I do wrong?
You're setting the binding on the TransformGroup, which has no Angle property. Instead of that you should set the binding directly on the RotateTransform.
var rotateTransform = new RotateTransform();
var tg = new TransformGroup();
tg.Children.Add(rotateTransform);
newImage.RenderTransform = tg;
var binding3 = new Binding("Angle");
...
BindingOperations.SetBinding(rotateTransform, RotateTransform.AngleProperty, binding3);

Categories

Resources