Specify a Path control using behind code in WPF - c#

I am trying to draw an ellipse using the Path control dynamically.
In my MainWindow():
EllipseGeometry ellipse = new EllipseGeometry(new Point(50, 50), 45, 20);
var path = new Path();
path.VerticalAlignment = VerticalAlignment.Top;
path.HorizontalAlignment = HorizontalAlignment.Left;
path.Fill = Brushes.Black;
path.Stroke = new SolidColorBrush(Colors.Green);
path.StrokeThickness = 2;
path.Data = ellipse;
but nothing shows up.
I realised that I need to "associate" the path object with my dialog box but I do not know how to do that. Is there a way to accomplish this via non-XAML methods since I will need to dynamically generate many different path objects?

All you are missing is basically that:
SamplePanel.Children.Add(path);
The above assumes that there is a Panel named SamplePanel in your window's XAML, e.g.
<Grid x:Name="SamplePanel" />

Related

Put a Composition effect behind a control

I've applied a shadow effect on a simple TextBlock control, but I've a problem : the shadow is in front of the Textblock and I don't know how to put the shadow behind the TextBlock. Do you have the solution for this problem ?
There is the code that creates the DropShadow effect:
public void SetupSimpleTextShadow(TextBlock shadowTarget)
{
Visual hostVisual = ElementCompositionPreview.GetElementVisual(shadowTarget);
Compositor compositor = hostVisual.Compositor;
DropShadow dropShadow = compositor.CreateDropShadow();
dropShadow.Color = Color.FromArgb(255, 50, 50, 50);
dropShadow.BlurRadius = 7f;
dropShadow.Offset = new Vector3(5f, 5f, 0f);
dropShadow.Opacity = 0.9f;
dropShadow.Mask = shadowTarget.GetAlphaMask();
SpriteVisual shadowVisual = compositor.CreateSpriteVisual();
shadowVisual.Shadow = dropShadow;
ElementCompositionPreview.SetElementChildVisual(shadowTarget, shadowVisual);
ExpressionAnimation bindSizeAnimation = compositor.CreateExpressionAnimation("hostVisual.Size");
bindSizeAnimation.SetReferenceParameter("hostVisual", hostVisual);
shadowVisual.StartAnimation("Size", bindSizeAnimation);
}
Try use XPShadow.The sample link is https://github.com/brookshi/XPShadow.
Finding the XPShadow in Nuget and download it.
Writing the ref NameSpace :xmlns:xp="using:XP"
In the code that you want the control have shadow,you can use the control in xp:Shadow.
<xp:Shadow CornerRadius="2"
IsCached="True"
Z_Depth="2">
<Control/>
</xp:Shadow>

Set Route Color in GMap.NET.WindowsPresentation

I am using the WPF version of Gmap.NET.
This feels like a stupid question....but I can't figure out how to change the stroke color/width of a route.
In winforms GMapRoute has property Stroke that can be set as you would expect
GMapRoute r = new GMapRoute(route.Points, "My route");
r.Stroke.Width = 2;
r.Stroke.Color = Color.TurdBrown;
The WPF version seems very different and I can't figure it out.
I could access to these properties using a casting, here is my code:
GMapRoute mRoute = new GMapRoute(route.Points);
mRoute.RegenerateShape(MainMap);
((System.Windows.Shapes.Path)mRoute.Shape).Stroke = new SolidColorBrush(Colors.Red);
((System.Windows.Shapes.Path) mRoute.Shape).StrokeThickness = 20;
Firts of all I created the GMapRoute, then I generated its shape in the map, then I modified the shape changing color and thickness.
I hope that this can help you.
I think use RegenerateShape for creating Shape is not good for performance.
It is better to setup style of line before adding route to map.
List<PointLatLng> routePath = List<PointLatLng>();
routePath.Add(new PointLatLng(Lat1,Lon1));
....
routePath.Add(new PointLatLng(LatN,LonN));
GMapRoute groute = new GMapRoute(routePath);
groute.Shape = new Path() { Stroke = new SolidColorBrush(Colors.Red), StrokeThickness = 4 };
map.Markers.Add(groute);

How to make the underlying control visible instead of form when set the trasparent backcolor

I have added two custom controls in the form as one control placed over the another control. Set the backcolor as trasparent for control1 but it shows the back color as form color instead of underlying control(control2) color. Please share your ideas . Thanks in advance.
Note : For example i have mentioned as picturebox but same problem raises for any controls such as richtextbox or placing the custom controls.
Image link : IssueImage
private void InitializeComponent()
{
#region picturebox
this.BackColor = Color.Aquamarine;
this.WindowState = FormWindowState.Normal;
var selectBtn = new Button();
selectBtn.Size = new Size(100, 30);
selectBtn.Location = new Point(10, 10);
selectBtn.Text = "Click";
//selectBtn.Click += selectBtn_Click;
var picturebox = new PictureBox();
picturebox.Size = new Size(140, 110);
picturebox.Location = new Point(4, 4);
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox.Image = new Bitmap(#"..\..\Data\graphic1.png");
var picturebox2 = new PictureBox();
picturebox2.Size = new Size(140, 110);
picturebox2.Location = new Point(4, 4);
picturebox2.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox2.Image = new Bitmap(#"..\..\Data\graphic1.png");
graphiccell = new GraphicCellControl();
graphiccell.Location = new Point(50, 200);
graphiccell.BackColor = Color.Transparent;
graphiccell.Size = new Size(160, 130);
var graphiccell2 = new GraphicCellControl();
graphiccell2.Location = new Point(100, 250);
graphiccell2.BackColor = Color.Red;
graphiccell2.Size = new Size(160, 130);
// graphiccell2.BackColor = Color.Transparent;
graphiccell.Controls.Add(picturebox);
graphiccell2.Controls.Add(picturebox2);
this.Controls.Add(graphiccell);
this.Controls.Add(graphiccell2);
this.Controls.Add(selectBtn);
#endregion
}
public class GraphicCellControl : Control
{
public GraphicCellControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
}
Transparency in Windows Forms follows the rules for Windows windows (ugh). This means that by default, you only get "proper" transparency when you're dealing with the parent-child relationship. Controls behind a transparent control will only be drawn if they are parents of said transparent control.
If this isn't feasible for you for some reason, you can always override the OnPaint or OnPaintBackground methods, and explicitly render whatever control you need to render regardless of the parent-child relationship. Of course, you'll quickly find why this isn't done by default if you can't do a few simplifying assumptions :)
As a quick list of what you need to do when there aren't any simplifications possible:
Find controls that are behind the transparent control - this is especially tricky when there isn't any spatial partitioning (like the mentioned parent-child relationship)
Render the relevant surfaces of the controls from 1. in back to front order on the current control's surface
Optimally, ensure that all the overlapping transparent controls avoid rendering the same controls multiple times
Ensure that all operations that can potentially change the background of the transparent control cause an invalidation (and thus re-render) of the transparent control's background

Clip an ellipse in WPF - positioning off

I am trying to 'cut' of part of several ellipses, in what is quite a big program. Since I had troubles making this work, I have started a new project in which I tried to solve the solution on a small scale. Again, I get some very weird results - which I expect have to do with positioning. Please see the below code for a minimal working example.
The program creates an ellipse, gives it a pretty colour and places it on the stage. It then proceeds to create what is called a 'RectangleGeometry', which we will use for the clipping. Please note that the geometry is placed at 0,0 with a width of 40 and height of 200. The result can be seen in the following screenshot;
My end goal is this: to be able to place a RectangleGeometry at any position (lets say 200,300) and have it clip the ellipse at exactly that position.
Ellipse abcEllipse = new Ellipse{
Margin = new Thickness(100, 100, 0, 0),
Fill = Brushes.HotPink,
Height = 80,
Width = 60
};
DrawCanvas.Children.Add(abcEllipse);
RectangleGeometry clipRectangle = new RectangleGeometry {
Rect = new Rect(0, 0, 40, 200)
};
GeometryGroup myGeometryGroup1 = new GeometryGroup();
myGeometryGroup1.Children.Add(clipRectangle);
Path myPath1 = new Path { Stroke = Brushes.Black, StrokeThickness = 1 };
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Color.FromArgb(255, 204, 204, 255);
myPath1.Opacity = 0.2;
myPath1.Fill = mySolidColorBrush;
myPath1.Data = myGeometryGroup1;
DrawCanvas.Children.Add(myPath1);
abcEllipse.Clip = clipRectangle;
Update: Some more clarification might indeed be required; I want to achieve the following effect - as seen in the attached image. An ellipse is placed on the stage, it is rotated and the top of the ellipse is cut off. (In such a way that it 'respects' the new rotation and thus cuts at what is now the new top)
However; this is the result I get when I apply the knowledge that "the clip geometry assigned to the shape will be relative to that shape;". As you can see, it doesn't really cut at the 'new' top of the ellipse.
Update 2: Added the code used to rotate the ellipse;
TransformGroup tg = new TransformGroup();
tg.Children.Add(new RotateTransform(40));
abcEllipse.RenderTransform = tg;

WPF: Creating image of dynamically created usercontrol

I want to create the image of a dynamically created usercontrol and show it in a window.
I am creating the usercontrol using the Below code .
MyViews.MyViewsUserControl myViewsCanvas = new MyViews.MyViewsUserControl(AllFoundationMyViewsViewModel,item.Id);
//myViewsCanvas.Height = 5;
//myViewsCanvas.Width = 5;
Size size = new Size(50, 50);
myViewsCanvas.Measure(size);
double width = myViewsCanvas.DesiredSize.Width;
double height = myViewsCanvas.DesiredSize.Height;
myViewsCanvas.Arrange(new Rect(new Point(), size));
Then i am creating the image of the myViewsCanvas and adding it to a view box of another usercontrol called _DashBoardUserControl using the below code.
_DashBoardUserControl.Viewbox2.Child = CreateImage(myViewsCanvas);
Then i am adding the _DashBoardUserControl to a window.
UserControls.Controls.PopupWindow popup = new UserControls.Controls.PopupWindow();
popup.PopupContent = _DashBoardUserControl;
popup.ShowDialog();
The problem is, I can only see a portion of the Image. I guess that is because of the measure() and arrange() methods. Can anybody tell me about these methods or what size should i pass to these methods. Do i need to scale down the image? If yes how do i do that?
The easiest way I know of is this:
Viewbox v = new Viewbox();
v.Child = uielem;
uielem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
v.Measure(uielem.DesiredSize);
v.Arrange(new Rect(new Point(), uielem.DesiredSize));
v.UpdateLayout();
r.Render(v);
where uielem is the element you want to render and r is the RenderTargetBitmap. (v.UpdateLayout might not be needed there, but I'm not sure anymore).

Categories