Drawing a stretchable Line in WPF - c#

I need to draw a line which stretch when its parent container stretch itself and it collapse when its parents collapse itself.
I develop a user control for this purpose and this control is placed in scroll viewer for some reasons.
I have binded the X2 Property of the line with the width of parent control. It solves the problem while stretching the parent control but while collapsing it is not letting the control decrease its size and scrollviewer adds a scrollbar for it.
Binding binding = new Binding("ActualWidth")
{
ElementName = Grid1.Name
};
Line mainLine = new Line
{
X1 = 0,
HorizontalAlignment=System.Windows.HorizontalAlignment.Stretch,
StrokeThickness = 2,
VerticalAlignment = VerticalAlignment.Center
};
BindingOperations.SetBinding(mainLine, Line.X2Property, binding);
Grid1.Children.Add(mainLine);
Grid.SetColumnSpan(mainLine, 4);

Try using a Rectangle to do that:
<Grid>
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Fill="Black"
Height="2"/>
</Grid>

Related

Visual elements in Livecharts?

I want to move a vertical line from the beginning of a Cartesian Chart to the end in a timespan of 5 seconds. I tried looking at the example provided in the website https://lvcharts.net/App/examples/v1/wpf/Visual%20Elements, but the UI Elements in the graph do not match with the code.
When I tried adding the line directly to the chart, the line works fine, but the chart is not showing up.
<lvc:CartesianChart Name="CartChart" Height="150" Zoom="Xy" Pan="Xy">
<lvc:CartesianChart.Series>
<lvc:LineSeries Values="{Binding audioPoints}" StrokeThickness="1" PointGeometry="{x:Null}" Visibility="Visible" />
</lvc:CartesianChart.Series>
<Line x:Name="anotherLine" Stroke="Black" Height="160" X1="0"X2="0" Y1="0" Y2="160"/>
</lvc:CartesianChart>
I found this code example that I think will demonstrate what you need to do. You should be able to translate most of it into databindings and xaml.
What's important to notice is that you add a VisualElement to the VisualElements collection on the CartesianChart. You set the UIElement property on the VisualElement object to be the WPF control you want added to your chart.
https://lvcharts.net/App/examples/v1/wf/Visual%20Elements
cartesianChart1.VisualElements.Add(new VisualElement
{
X = 0.5,
Y = 7,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Top,
UIElement = new TextBlock //notice this property must be a wpf control
{
Text = "Warning!",
FontWeight = FontWeights.Bold,
FontSize = 16,
Opacity = 0.6
}
});
cartesianChart1.VisualElements.Add(new VisualElement()
{
X=0,
Y=myCalculatedValue,
UIElement = new Rectangle()
{
Width= width,
Margin= new Thickness(-seriesWidth/2, 0, 0, 0),
Height=6,
Fill=Brushes.Black,
VerticalAlignment = VerticalAlignment.Top
}
});

How can you outline an ellipse without using stroke property?

What I really want is a way to have a negative stroke Thickness value on a WPF shape such as an ellipse, so that the stoke outline paints outwards towards LEFT and TOP of Shape, rather than inside of the shape, over writing my text when I make the thinkness of the stroke too thick... I want the radius of my ellipse to stay constant, but the stroke to grow outwards with increased thinkness, and the LEFT, TOP placement of the shape to remain contant with the inner fill staying the same size and not getting covered up by stroke as it is increased in size.
I tried DropShadowEffect, but its kind of too blurry and not well defined enough...and looks kind of messy... really I just want a solid line going around the outside of the shape...
As you can see from attached picture above, I tried to put shadow around two the ellipses using this code below. the problem is that I want it to be a solid color around the outside like a scaletransform of another ellipse of a different color.
var e = new Ellipse();
DropShadowEffect effect = new DropShadowEffect();
effect.Color =Colors.Orange;
effect.Direction = 0;
effect.BlurRadius = 30;
effect.ShadowDepth = 4;
effect.Opacity=0;
e.Effect = effect;
t.Text = string.Format("abc");
t.Measure(new Size(gwin.XStep, gwin.YStep));
t.Arrange(new Rect(t.DesiredSize));
e.StrokeThickness = 2;
e.Stroke = Brushes.Black;
canvas.Children.Add(e);
canvas.Children.Add(t);
Another possible direction towards solving the problem:
<Ellipse RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<ScaleTransform/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
Convert to c# code and place one scaletransform ellipse centered inside another scaled transform ellipse of different colors... not sure how to set it up though.
Solution:
Based on suggestion below. I tried creating a grid, setting the width and height of the grid to the size of my ellipse, then adding two ellipses to the grid with different colors and one with a margin set to -10. and it works perfectly ... just need to place the larger ellipse with margin -10 behind the other ellipse when adding it to the grid...here's what it looks like now..
Solution is in here somewhere:
g = new Grid();
e = new Ellipse();
h = new Ellipse();
t = new TextBlock();
t.HorizontalAlignment = HorizontalAlignment.Center;
t.VerticalAlignment = VerticalAlignment.Center;
t.FontWeight = FontWeights.ExtraBold;
g.Children.Add(h);
g.Children.Add(e);
g.Children.Add(t);
gwin.canvas.Children.Add(g);
t.Text = String.Format("{0}.{1}", x, y);
g.Width = gwin.XStep;
g.Height = gwin.YStep;
Canvas.SetLeft (g, gwin.X1 + gwin.XStep*x*2);
Canvas.SetTop (g, gwin.Y1 + gwin.YStep*y*2);
e.StrokeThickness = 2;
e.Stroke = Brushes.Black;
h.Margin = new Thickness(-10);
You can use double ellipses inside a grid overlaying each other like this:
<Grid Width="100" Height="100">
<Ellipse Fill="Black" Margin="-10"/>
<Ellipse Fill="Red" />
</Grid>
The size of this compound is still 100x100 even though the first ellipse is bigger and rendered out of its boundaries.
You may also use a Path and then do this
I think there is something like border. Or you can draw one elipse and then a second one in smaller that has the background color.

Rendered Rectangles missing in a huge WPF Control

I need a WPF Control with 300000000 Width and Height, on which I will draw Rectangles, based on some input. I am drawing the Rectangle on the OnRender of the control. For testing purpose I have put the control inside a ScrollViewer and am drawing Rectangles on each pixels from (0,0) to (1000,1000). If the Width & Height is 1000000, the Rectangles are drawn properly, shown below, (the Rectangles are plotted on all the pixels from (0,0) to (1000,1000), so it looks like the on in the below link)
https://social.msdn.microsoft.com/Forums/getfile/950012
But If I increase the size to 3000000, few lines are missing in the drawing like below,
https://social.msdn.microsoft.com/Forums/getfile/950018
My Xaml:
<ScrollViewer x:Name="MainScrollViewer"
Grid.Row="2"
Grid.ColumnSpan="2"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<waferControl:WaferMapControl x:Name="WaferControl"
Grid.Row="2"
Grid.ColumnSpan="2"
Width="30000000"
Height="30000000"
Margin="10"
ColumnCount="{Binding WaferInfo.ColumnCount}"
RowCount="{Binding WaferInfo.RowCount}"
SelectedCells="{Binding SelectedCellCollection}"
Visibility="Collapsed" />
</ScrollViewer>
I am using the following code in OnRender of WaferMapControl.
private void RenderBackgroud(IEnumerable lists`enter code here`)
{
using (DrawingContext dc = _backgroundDv.RenderOpen())
{
SolidColorBrush brush = Brushes.Black;
if (brush.CanFreeze)
brush.Freeze();
foreach (GridCellInfo cellInfo in lists)
{
double length = cellInfo.GridRange;
var point = new Point(
cellInfo.RowIndex + 1,
ActualHeight - cellInfo.ColumnIndex - length);
RenderBackgroud(dc, point, brush, length);
}
}
}
private void RenderBackgroud(DrawingContext dc, Point point, Brush brush, double length)
{
var rect = new Rect(point, new Size(length, length));
dc.DrawRectangle(brush, null, rect);
}
The cellInfo contains the x,y coordinates. The point calculation is done to draw from the bottom left. The length is 1 in my sample.
Can someone help me out, what is the issue here. Let me know if you require anything from my side.

How to add text as content in Rectangle C# WPF

I have the following rectangle, which is filled with color. i want to add some text inside in middle of the box. please suggest some solution.
var rect1 = new Rectangle
{
Stroke = new SolidColorBrush(Colors.Red),
Fill = new SolidColorBrush(Colors.Black),
Width = 150,
Height = 100,
VerticalAlignment = System.Windows.VerticalAlignment.Top,
HorizontalAlignment = System.Windows.HorizontalAlignment.Left
};
Grid.SetRow(rect, 0);
TGrid2.Children.Add(rect1);
Basically i want to make a drag and drop feature. where rect1 will be dragged over rect2; which will only have border color and transparent Fill-body and on drop replaces rect2 with dropped rect1.
Thats why i made a rectangle and now trying to figure how to add text in rectangle as content in center, similar like a button.
If you absolutely must use a rectangle, you could fake it!
<Grid>
<Rectangle Fill="Red"/>
<TextBlock Text="Hi there" Margin="5"/>
</Grid>
Replace the Rectangle by a Grid or a Border and put a TextBlock inside.

TransformToVisual to element in a different visual tree within the same window

This is related to some custom drag and drop functionality I am implementing.
Everything was working very well until I threw a ContentPresenter into the mix.
I have a Window which contains a ContentPresenter.
The Content of this ContentPresenter is Bound different usercontrols which are popped in and out dynamically.
The problem I'm having is I need to perform a TransformToVisual on a control contained within the ContentPresenter relative to a control that lives outside in the main window where this COntentPresenter resides.
Summary:
Window -> Canvas called MyCanvas -> ContenPresenter (Content Presenter contains a ListView called MyListView)
I want to call MyListView.TransformToVisual(MyCanvas).
This is seemingly not allowed as I receive the error: "The specified Visual and this Visual do not share a common ancestor, so there is no valid transformation between the two Visuals."
Notes on snippet below:
1. _targetBoundingBoxes is a List of UIElements which should accept a drag
2. As I drag, I move a canvas around the screen (_canvasThatIsBeingDraggedAround).
3. As it moves, I am querying to see if the current MousePosition falls within any of the _dropTargets.
Code snippet that is failing:
_targetBoundingBoxes.Clear();
foreach (var item in _dropTargets)
{
GeneralTransform t = item.TransformToVisual(_canvasThatIsBeingDraggedAround);
Rect _dropBoundingBox = t.TransformBounds(new Rect(0, 0, item.RenderSize.Width, item.RenderSize.Height));
_targetBoundingBoxes.Add(item, _dropBoundingBox);
}
<Window>
<StackPanel>
<Button Margin="0,50,0,0" Height="50"/>
<ContentPresenter Name="HI" Content="{Binding Blah}"/>
</StackPanel>
</Window>
//Create a canvas which will be used as the dragged adorner. Canvas is used since you can set the Left and Top positions.
if (_topWindow.FindName("adornerLayer") == null)
{
//grab the existingContent
UIElement existingContent = (UIElement)_topWindow.Content;
//create a Grid wrapper around the entire window content so we can add the new canvas adornerLayer as a child in addition to the existing content
Grid nonLayoutCanvas = new Grid(); nonLayoutCanvas.VerticalAlignment = VerticalAlignment.Stretch; nonLayoutCanvas.HorizontalAlignment = HorizontalAlignment.Stretch;
//create the hidden Canvas that we will draw to and move around the screen
Canvas adornerCanvas = new Canvas(); adornerCanvas.Visibility = Visibility.Collapsed; adornerCanvas.Name = "adornerLayer";
adornerCanvas.Effect = new DropShadowEffect() { ShadowDepth = 5, BlurRadius = 5, Color = Colors.Silver };
//reset the content to the nonLayout Canvas
_topWindow.Content = nonLayoutCanvas;
//add the original content and the new canvas to the grid above
nonLayoutCanvas.Children.Add(existingContent);
nonLayoutCanvas.Children.Add(adornerCanvas);
_topWindow.RegisterName("adornerLayer", adornerCanvas);
}
_canvasThatIsBeingDraggedAround = (Canvas)_topWindow.FindName("adornerLayer");
Change TransformToVisual to TransformToAncestor.

Categories

Resources