I have a Slider Binded to the ScaleX of a Line, like the following code:
/* Graphics on Canvas */
Line lR = new Line();
lR.X1 = 0;
lR.Y1 = 0;
lR.X2 = 150;
lR.Y2 = 150;
lR.Stroke = new SolidColorBrush(Colors.Blue);
lR.StrokeThickness = 2;
/* declare ScaleTransformation */
ScaleTransform lRSt = new ScaleTransform();
TransformGroup lRTran = new TransformGroup();
lRTran.Children.Add(lRSt);
lR.RenderTransform = lRTran;
Binding sliderRBind1 = new Binding();
sliderRBind1.Source = sliderR;
sliderRBind1.Path = new PropertyPath("Value");
BindingOperations.SetBinding(lRSt, ScaleTransform.ScaleXProperty, sliderRBind1);
BindingOperations.SetBinding(lRSt, ScaleTransform.ScaleYProperty, sliderRBind1);
/* Slider - Slider should be placed outside the canvas to prevent being redrawn */
Slider sliderR = new Slider();
sliderR.Minimum = 1;
sliderR.Maximum = 3;
sliderR.Value = 1;
sliderR.TickPlacement = TickPlacement.BottomRight;
sliderR.TickFrequency = 0.2;
sliderR.IsSnapToTickEnabled = true;
Code works fine. But if I move the ScaleTransform to a method, the Binding is lost.
/* Graphics on Canvas */
Line lR = new Line();
lR.X1 = 0;
lR.Y1 = 0;
lR.X2 = 150;
lR.Y2 = 150;
lR.Stroke = new SolidColorBrush(Colors.Blue);
lR.StrokeThickness = 2;
/* declare ScaleTransformation */
ScaleTransform lRSt = new ScaleTransform();
TransformGroup lRTran = new TransformGroup();
lRTran.Children.Add(lRSt);
lR.RenderTransform = lRTran;
LineSliderR(lR);
/* Slider - Slider should be placed outside the canvas to prevent being redrawn */
Slider sliderR = new Slider();
sliderR.Minimum = 1;
sliderR.Maximum = 3;
sliderR.Value = 1;
sliderR.TickPlacement = TickPlacement.BottomRight;
sliderR.TickFrequency = 0.2;
sliderR.IsSnapToTickEnabled = true;
public void LineSliderR(Line lRSt)
{
Binding sliderRBind1 = new Binding();
sliderRBind1.Source = sliderR;
sliderRBind1.Path = new PropertyPath("Value");
BindingOperations.SetBinding(lRSt, ScaleTransform.ScaleXProperty, sliderRBind1);
BindingOperations.SetBinding(lRSt, ScaleTransform.ScaleYProperty, sliderRBind1);
}
Why did the Binding fail if it's called to a separate method?
The two codes are (to me) identical. Both contain four same, identical, "things":
a Line, a ScaleTransform, a Binding, and a Slider.
The first code has all 4 "things" in a function. The second code has the Binding call from a separate function. Both compiles without error: However, the Binding (between Line and Slider) works OK on the first code, but not the second. I am trying get the second code to work because I have many Line's and I don't want to repeat myself.
In your second code block, inside the method LineSliderR, lRSt is an object of type Line, while in your first block it is of type ScaleTransform.
If you want your second block to behave like the first, your method LineSliderR, should accept a ScaleTransform' as parameter:
public void LineSliderR(ScaleTransform lRSt)
Related
I am trying to display different shapes on Content Presenter in wpf, I am able to show Rectangle but Line object is not getting populated, Can anyone help me with this
Line r = new Line();
r.SetValue(Canvas.TopProperty, 50.0);
r.SetValue(Canvas.LeftProperty, 10.0);
r.X1 = 50;
r.Y1 = 50;
r.X2 = 150;
r.Y2 = 150;
r.Width = 200;
r.StrokeThickness = 5.0;
r.Fill = new SolidColorBrush(Colors.Green);
ContentComponent.Content = r;
You should set the Stroke property to a Brush:
r.Stroke = Brushes.Green;
Note that there is no reason to create a new green brush using new SolidColorBrush(Colors.Green) instead of using the static Green property of the Brushes class.
From within MainWindow ctor :
for(var i = 0; i <5; i++)
{
var button = new Button {};
button.LayoutTransform = new RotateTransform(i * 10);
button.Width = 300;
button.Height = 300;
TempCanvas.Children.Add(button);
}
This produces the following:
Please can someone explain why this is happening. I am expecting the 5 buttons to be rotated through the same point.
I did not want to RenderTransform as the graphics that I will be rendering would be drawn outside of the parent and not reflected in the measure.
The Canvas is the issue, unlike other contains it is not constrained in its physical size, it stretches out to infinity in all directions. Therefore it's rotation origin is not the canvas.width/2 by canvas.height/2.
If you repeat your code in a grid or dockpanel you will get the required result.
Do you want something like this:
Code:
for (var i = 0; i < 5; i++)
{
var button = new Button { };
//button.LayoutTransform = new RotateTransform(i * 10);
button.RenderTransform = new RotateTransform(i * 10);
button.Width = 300;
button.Height = 300;
button.Margin = new Thickness(200, 0, 0, 0);
TempCanvas.Children.Add(button);
}
I am trying to draw a vertical line that is anchored to a point. I tried to use the height of my Y axis which is fixed to draw the line, but it wasn't centered correctly. So right now I have an infinite line, but that I want is the line to just fill the graph like so
VerticalLineAnnotation lineannot = new VerticalLineAnnotation();
lineannot.AnchorDataPoint = chart.Series[item].Points.Last();
lineannot.LineColor = Color.Red;
lineannot.Width = 3;
lineannot.Visible = true;
lineannot.IsInfinitive = true;
chart.Annotations.Add(lineannot);
IsInfinitive is complemented by ClipToChartArea; you can set the line to be clipped to a ChartArea like this:
lineannot.ClipToChartArea = chart.ChartAreas[item].Name;
assuming item is the right area name or index..
Note that ClipToChartArea takes the name of the chart area!
This is the simplest way to do it.
It is also possible to control an annotation's position and size directly:
// Note that directly after adding points this will return NaN:
double maxDataPoint = chart1.ChartAreas[0].AxisY.Maximum;
double minDataPoint = chart1.ChartAreas[0].AxisY.Minimum;
LineAnnotation annotation2 = new LineAnnotation();
annotation2.IsSizeAlwaysRelative = false;
annotation2.AxisX = chart1.ChartAreas[0].AxisX;
annotation2.AxisY = chart1.ChartAreas[0].AxisY;
annotation2.AnchorY = minDataPoint;
annotation2.Height = maxDataPoint - minDataPoint;;
annotation2.Width = 0;
annotation2.LineWidth = 2;
annotation2.StartCap = LineAnchorCapStyle.None;
annotation2.EndCap = LineAnchorCapStyle.None;
annotation2.AnchorX = 21; // <- your point
annotation2.LineColor = Color.Pink; // <- your color
chart1.Annotations.Add(annotation2);
i am trying to make a animation in which all the elements of my particular grid should vibrate.
so i tried this code ..
Storyboard hintstoryboard = new Storyboard();
for (int i = 3; i < gridpieces.Children.Count; i++)
{
DoubleAnimationUsingKeyFrames doubleanimation = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTargetName(doubleanimation, ((Image)gridpieces.Children[i]).Name);
Storyboard.SetTargetProperty(doubleanimation, "(UIElement.Projection).(PlaneProjection.RotationZ)");
EasingDoubleKeyFrame frame = new EasingDoubleKeyFrame();
frame.KeyTime = TimeSpan.FromSeconds(0.1);
frame.Value = -5;
EasingDoubleKeyFrame frame1 = new EasingDoubleKeyFrame();
frame1.KeyTime = TimeSpan.FromSeconds(0.2);
frame1.Value = 0;
EasingDoubleKeyFrame frame2 = new EasingDoubleKeyFrame();
frame2.KeyTime = TimeSpan.FromSeconds(0.3);
frame2.Value = 5;
EasingDoubleKeyFrame frame3 = new EasingDoubleKeyFrame();
frame3.KeyTime = TimeSpan.FromSeconds(0.4);
frame3.Value = 0;
doubleanimation.KeyFrames.Add(frame);
doubleanimation.KeyFrames.Add(frame1);
doubleanimation.KeyFrames.Add(frame2);
doubleanimation.KeyFrames.Add(frame3);
hintstoryboard.Children.Add(doubleanimation);
}
hintstoryboard.Begin();
but it is giving an exception that target name is not found but my grid have the image with same same name... i have made that grid by code only...
Any help will be appreciated.
I don't think you can use SetTargetName outside of XAML. In code behind you should replace this:
Storyboard.SetTargetName(doubleanimation, ((Image)gridpieces.Children[i]).Name);
with this
Storyboard.SetTarget(doubleanimation, (Image)gridpieces.Children[i]);
I have class, that creates Shapes for me (I tried to create some kind of "class factory" but im not sure if this is correct term for that I have created.
Problem is described in comments in my code.
public static Ellipse SomeCircle()
{
Ellipse e = new Ellipse();
double size = 10;
e.Height = size;
e.Width = size;
e.Fill = new SolidColorBrush(Colors.Orange);
e.Fill.Opacity = 0.8;
e.Stroke = new SolidColorBrush(Colors.Black);
// i want to have something like this here:
// canvas1.Children.Add(e);
// but I cant access non-static canvas1 from here
// I need this to place my ellipse in desired place
// (line below will not work if my Ellipse is not placed on canvas
// e.Margin = new Thickness(p.X - e.Width * 2, p.Y - e.Height * 2, 0, 0);
return e;
}
I have no idea how to workaround this.
I don't want to pass that canvas by parameter in my whole application...
Since you do not want to pass your Canvas around as a parameter, you could try creating an Extension Method which would act on your Canvas Object.
namespace CustomExtensions
{
public static class Shapes
{
public static Ellipse SomeCircle(this Canvas dest)
{
Ellipse e = new Ellipse();
double size = 10;
e.Height = size;
e.Width = size;
e.Fill = new SolidColorBrush(Colors.Orange);
e.Fill.Opacity = 0.8;
e.Stroke = new SolidColorBrush(Colors.Black);
dest.Children.Add(e);
return e;
}
}
}
Usage remember to add the CustomExtensions Namespace to your usings.
canvas1.SomeCircle();