WPF - Setting corner radius in code behind - c#

I want to bring a some rectangles to my WPF-Pages, these Rectangles should have rounded corners. To bring a few of the rectangles to the page without having to write every single one in xaml I decided to do it with a loop in the code.
I tried this one:
for (int i = 0; i < 5; i++)
{
Rectangle rect = new Rectangle();
rect.Fill = System.Windows.Media.Brushes.Green;
var style = new Style(typeof(Border));
style.Setters.Add(new Setter(Border.CornerRadiusProperty, new CornerRadius(12.0, 0, 0 , 0)));
rect.Resources.Add(typeof(Border), style);
Grid.SetColumn(rect, 1);
Grid.SetRow(rect, 1);
mainGrid.Children.Add(rect);
}
but the corner radius of my rectangles won´t change. Do you have any suggestion?
Thanks for your help in advance!

To bring a few of the rectangles to the page without having to write every single one in xaml
Good problem to solve.
I decided to do it with a loop in the code
Absolutely bad solution. Use proper MVVM with an <ItemsControl> bound to your list of objects you're trying to display, stored in your view model. And then create a global style sheet and apply it to this either automatically or manually.
Anyway to answer your question, you're creating an unnamed style on Border and applying it to a Rectangle. That will never auto-apply, and good thing, because you reference Border.CornerRadiusProperty which doesn't exist on a Rectangle.
You want to either make your style override the Rectangle's template and add a Border around it, then set its corner border radius, or manually add the border above the rectangle and set its corner radius in your setter (only add the style to the Border's resources).
Your code doesn't really make sense to me though, Rectangle also has corner radius properties, RadiusX and RadiusY, you could just set those if that's what you want.

The rectangle is overflowing. If you do the same thing with a border it will work. When you add the rectangle inside the border you can see what its doing
Rectangle rect = new Rectangle();
rect.Fill = System.Windows.Media.Brushes.Green;
Border b = new Border();
b.Width = 100;
b.Height = 100;
b.Background = Brushes.White;
b.CornerRadius= new CornerRadius(12, 0, 0, 0);
b.BorderThickness = new Thickness(2);
b.BorderBrush = Brushes.Red;
b.Child = rect;//adding this rectangle will show you how the corner is overflowing
grid_Main.Children.Add(b);

Related

Programmatically created UIElement 'unlinks' when local variable value is set to a new UIElement

Hopefully the title isn't to vague, I'm not sure how else to word it. What I'm trying to do (As a basic example) is add a rectangle to a canvas programmatically, then at some later point change the local variable to a new rectangle with different properties and have that update on the canvas.
// First rectangle
Rectangle rect = new Rectangle()
{
Width = 50,
Height = 50,
Fill = Brushes.Red,
Margin = new Thickness(20, 20, 0, 0)
};
// Add it to the canvas
mainCanvas.Children.Add(rect);
// Change something about the rectangle, which works
rect.Fill = Brushes.Black;
// Create new rectangle
Rectangle newRect = new Rectangle()
{
Width = 15,
Height = 20,
Fill = Brushes.Blue,
Margin = new Thickness(20, 20, 0, 0)
};
// Set the original rectangle to the new rectangle
rect = newRect;
// Canvas rectangle is no longer 'linked' to the rect variable :(
You are reassigning a the rect variable, but that doesn't affect your Canvas. The Canvas only knows about the old rectangle rect used to point to. rect is just a reference to a rectangle. When you add it to the canvas, the canvas copies the reference. It doesn't continue to use the rect variable anymore. So changing rect to reference a new rectangle changes nothing for the canvas, as the canvas still references the original.
You likely will want to do something like the following. I'm just taking a stab here, so you might need to look up appropriate methods, but hopefully this gives you guidance.
mainCanvas.Children.Remove(rect); //take the old rectangle off the canvas
rect = newRect;
mainCanvas.Children.Add(rect); //replace the new rectangle on the canvas

How to draw a rectangle with a background color in WPF

Hi I want to have a rectangle like the below picture to fill the entire canvas with different sizes and at different position scatter through out the canvas. My solution environment is WPF C#
Could some one please guide me of how to do it? Till now what I have done is canvas_loaded
Rectangle rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Black);
rect.Width = 100;
rect.Height = 100;
rect.Stroke = new SolidColorBrush(Colors.Black);
But the problem here how will I position it to the different locaion of the canvas, the size and width I can provide at run time with different value but I need to position the rectangles (Square) at diffrent XY co-ordinates so that none of the rectangles or Squares overlapp each other.
Please help.
You can use
Canvas.SetLeft(rect, <offset>) Canvas.SetRight(...), Canvas.SetTop(...), Canvas.SetBottom(...)
to position UIElement in the Canvas container.
Use Random class to generate the xy co-ordinates
Random r=new Random();
r.Next(1,100);

Get chart area bounds in C#

Just to explain what I'm doing, I draw two selectors on a chart, and the part that will not be selected should appear under that blue rectangle. The part that will be selected will appear in the white area, between the two selectors. The figure below shows only the left selector.
Now, what I'm trying to do is to draw a rectangle inside a chart that always remain inside the plotting area, even when the windows is resized.
To get the top, left and bottom bounds, to draw the rectangle as shown in the figure below, I do the following:
(...)
int top = (int)(Chart.Height * 0.07);
int bottom = (int)(Chart.Height - 1.83 * top);
int left = (int)(0.083 * Chart.Width);
Brush b = new SolidBrush(Color.FromArgb(128, Color.Blue));
e.Graphics.FillRectangle(b, left, top, marker1.X - left, bottom - top);
(...)
But that's far from perfect, and it isn't drawn in the right place when the window is resized. I want the blue rectangle to always be bound on the top, left and bottom by the plotting area grid. Is that possible?
You probably want to use StripLine to achieve this.
Look into the Stripline Class Documentation.
Also I recommend downloading the Charting Samples which are a great help to understand the various features.
StripLine stripLine = new StripLine();
stripLine.Interval = 0; // Set Strip lines interval to 0 for non periodic stuff
stripLine.StripWidth = 10; // the width of the highlighted area
stripline.IntervalOffset = 2; // the starting X coord of the highlighted area
// pick you color etc ... before adding the stripline to the axis
chart.ChartAreas["Default"].AxisX.StripLines.Add( stripLine );
This assumes you are wanting something that is not what Cursor already does (see CursorX), such as letting the user mark up areas of the plot which provides some persistence. Combining the Cursor events with the striplines above would be a good way to do that.
So to highlight the start and end of the cursor you could do this
// this would most likely be done through the designer
chartArea1.AxisX.ScaleView.Zoomable = false;
chartArea1.CursorX.IsUserEnabled = true;
chartArea1.CursorX.IsUserSelectionEnabled = true;
this.chart1.SelectionRangeChanged += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CursorEventArgs>(this.chart1_SelectionRangeChanged);
...
private void chart1_SelectionRangeChanged(object sender, CursorEventArgs e)
{
chart1.ChartAreas[0].AxisX.StripLines.Clear();
StripLine stripLine1 = new StripLine();
stripLine1.Interval = 0;
stripLine1.StripWidth = chart1.ChartAreas[0].CursorX.SelectionStart - chart1.ChartAreas[0].AxisX.Minimum;
stripLine1.IntervalOffset = chart1.ChartAreas[0].AxisX.Minimum;
// pick you color etc ... before adding the stripline to the axis
stripLine1.BackColor = Color.Blue;
chart1.ChartAreas[0].AxisX.StripLines.Add(stripLine1);
StripLine stripLine2 = new StripLine();
stripLine2.Interval = 0;
stripLine2.StripWidth = chart1.ChartAreas[0].AxisX.Maximum - chart1.ChartAreas[0].CursorX.SelectionEnd;
stripLine2.IntervalOffset = chart1.ChartAreas[0].CursorX.SelectionEnd;
// pick you color etc ... before adding the stripline to the axis
stripLine2.BackColor = Color.Blue;
chart1.ChartAreas[0].AxisX.StripLines.Add(stripLine2);
}
Somehow I suspect you may not have discovered the cursor yet, and doing so will make all this irrelevant. But anyway, the above code will do what you described.

C# WPF - Adorner ZIndex

I have a Grid with a Adorner to provide some drawn pattern. See img: http://imgur.com/D649W
My problem is that this Adorner(dots on the Grid) is layered on top of everything. The white square are draggable but now when the Adorner are on top, I can't drag. I would like the layer to be behind every component added to the Grid. Any suggestions on how I can set the ZIndex?
Thanks.
Code below:
MyAdorner ad = new MyAdorner(grid);
AdornerLayer adLayer = AdornerLayer.GetAdornerLayer(grid);
adLayer.Add(ad);
I push my Button and this is adding the MyAdorner to the grid. MyAdorner looks like this:
public MyAdorner(Grid adornedGrid)
: base(adornedGrid) {
Height = adornedGrid.Height;
Width = adornedGrid.Width;
brush = new VisualBrush();
brush.Stretch = Stretch.Fill;
brush.TileMode = TileMode.Tile;
brush.Viewport = new Rect(0, 0, SnapDistance, SnapDistance);
brush.ViewportUnits = BrushMappingMode.Absolute;
brush.Viewbox = new Rect(0, 0, SnapDistance, SnapDistance);
brush.ViewboxUnits = BrushMappingMode.Absolute;
ellipse = new Ellipse() { Fill = new SolidColorBrush(Colors.Blue), Width = 2, Height = 2 };
brush.Visual = ellipse;
}
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) {
Pen renderPen = new Pen(new SolidColorBrush(Colors.Black), 0);
drawingContext.DrawRectangle(brush, renderPen, new Rect(new Point(0, 0), AdornedElement.DesiredSize));
}
If your problem is that the adorner is covering the elements you want to manipulate so that they become un-draggable etc, set .IsHitTestVisible = False on the adorner.
You can also set the adorner's opacity to some semi-transparent value to see the background through it if that is desirable.
Is this what you're looking for?
Panel.SetZIndex(ad, 20)
Attached properties of the framework are usually asignable from static methods of the UIElement that holds it.
EDIT:
Possible alternative: - make your own Panel
Easy and dirty way to make sure that your wanted elements are ALWAYS on top:
Declare a static in a Util library:
public static int ZIndexCount;
Then when you want an element on top you simply do:
SetZIndex(_viewbox, Util.ZIndexCount++);
Of course, if your application runs 5 years without being interrupted the ZIndexCount will go back to 0...
It works like a charm in my applications.
I know this is quite old but I thought I try anyway:
You can add a new AdornerDecorator to you visual tree hierarchy to render the controls at the right level. By default the root of the tree provides the AdornerDecorator but you can add as many as you want and your the components you add will be rendered in them. For more information - see here
<Grid>
<AdornerDecorator>
...your Adorners render here
</AdornerDecorator>
</Grid>
https://wangmo.wordpress.com/2008/10/19/relations-between-adorner-adornerlayer-and-adornerdecorator/

Merging Shapes and Attaching Partial Drag/Drop in WPF

I would like to draw two shapes in WPF and merge them together. Then, I'd like to attach a drag/drop event to ONE of the original shapes.
So basically, you can only drag if you click on a certain part of the shape, but it will drag the entire shape with you.
Here is some code:
// Set up some basic properties for the two ellipses
Point centerPoint = new Point(100, 100);
SolidColorBrush ellipseColor_1 = new SolidColorBrush(Color.FromArgb(255, 0, 0, 255));
double width_1 = 10; double height_1 = 10;
SolidColorBrush ellipseColor_2 = new SolidColorBrush(Color.FromArgb(50, 255, 0, 0));
double width_2 = 200; double height_2 = 200;
// Create the first ellipse: A small blue dot
// Then position it in the correct location (centerPoint)
Ellipse ellipse_1 = new Ellipse() { Fill = ellipseColor_1, Width = width_1, Height = height_1 };
ellipse_1.RenderTransform = new TranslateTransform(point.X - width_1 / 2, point.Y - height_1 / 2);
// Create the second ellipse: A large red, semi-transparent circle
// Then position it in the correct location (centerPoint)
Ellipse ellipse_2 = new Ellipse() { Fill = ellipseColor_2, Width = width_2, Height = height_2 };
ellipse_2.RenderTransform = new TranslateTransform(point.X - width_2 / 2, point.Y - height_2 / 2);
// ???
// How should I merge these?
// ???
// Now apply drag drop behavior to ONLY ellipse_1
MouseDragElementBehavior dragBehavior = new MouseDragElementBehavior();
dragBehavior.Attach(ellipse_1); // This may change depending on the above
// ...
// Add new element to canvas
This code creates two circles (a big one and a small one). I would like to only be able to drag if the small one is clicked, but I'd like to have them attached so they'll move together without having to manually add code that will take care of this.
If you put them both in a Grid (or Canvas, StackPanel, etc.), and set the drag behavior on the panel, they will be "merged". If you set IsHitTestVisible to false on ellipse_2, it won't respond to any mouse events, so effectively it won't be draggable.

Categories

Resources