Create shadow in WPF without using effect - c#

the problem is following: we have an application that shows live image within a control called Display. There can be (potentially interactive) layers on top of the live image within the Display control (Display control is basically a Grid with LiveImageLayer at the bottom). Most available layers consist of line graphics to not obsure the image. Some layers are composed of standard WPF controls like buttons or sliders (with altered template so they're rendered using line graphics). Some layers are even drawn directly using DrawingContext.
To improve visibility and readability of the layer graphics on top of live noisy image, we tried to assing DropShadow effect to the layers. This worked very well from visual point-of-view. However, it was very bad from performance point-of-view. Due to fast update of ImageLayer (up to 60Hz), DropShadow effects got recalculated for all layers with the image update frequency (even if layers themselves do not change).
We can implement old-fashioned shadow (same graphics with black pen-and-brush below, shifted to the lower right) manually for each layer. And we'll actually do it if there's no better way.
So, my question is: is there any automatic or semi-automatic way to achieve such shadow? I thought of creating shifted rectangle below the actual layer, which brush set to visual brush of the actual layer. However, I found no way (other than Effect) to re-color the visual brush to black.
Any ideas?

I had similar performance issues with shodows a while back, I ended up just using Border to make a fake shadow, However in my Usercontrols I used a LinearGradientBrush that made the shadow a bit more realistic but I can't remember the brush settings, But this is kind of the effect it created.
<Grid>
<Border Margin="57,74,162,114" BorderThickness="2,0,0,2" CornerRadius="5" BorderBrush="#AA000000">
<Button Content="StackOverflow" />
</Border>
</Grid>
Its a bit of a bummer that WPF Effects are CPU rendered as shadows to solve issues like your describing.

Related

System.Windows.Media.DrawingContext.DrawImage() showing white pixels instead of black in semi-transparent areas like shadows

I have a WPF Button subclass that overrides OnRender() to draw one of several bitmaps depending on the current state. The simplified (1-bitmap) code is shown below...
protected override void OnRender(DrawingContext context)
{
context.DrawImage(_MyBitmapSource, new Rect(0, 0, Width, Height));
}
The semitransparent black pixels of the shadows in each bitmap incorrectly render as semitransparent white.
Likewise if I set one of these images as the Background brush the same thing happens.
For Image controls setting the same image to Source looks correct, so I know WPF is able to draw the shadows correctly. I'm obviously missing something — possibly something else that needs to be set in OnRender() before the call to DrawImage().
There's nothing special about the PNG images. Just to be certain that wasn't the problem I downloaded a few PNGs from images.google.com and they all had the same issue.
In other frameworks, events such as Paint or Render are usually used to change look of controls.
WPF has lookless controls - you can template a wpf control to be just about anything you can imagine. This is rather mind numbing, extremely powerful and makes some things way easier than they would be in those other frameworks.
Hence the "conventional" wpf approach to creating an image that has the behaviour of a button is just to set the template of a button to an image. You can then set imagessource by code or markup. Markkup is usually preferred by WPF developers and you have multiple options including datatriggers, triggers, templating and visual states.
Other benefits of this approach are that markup allows you to get an immediate idea of what will happen and you can fairly easily simplify it right down for any trouble shooting.

Toolbar on right side of the screen in wpf

I am trying to make a WPF application in which there is a drag able toolbar on the screen through which user can select different type of tools and use it on canvas. Also can someone tell me how to make a transparent canvas. A good example would be from this picture in which there is drag able toolbar on right side of the picture. And the user can also work on any window he wants. I am new to WPF and I am trying to find a solution to my problem for quite a while now. Can someone guide me in the right direction...
Background DP default value is null. When a Background is set to null the displayed Color is White and mouse interactions don't work. You need to set Canvas's, ListBox's and ListBoxItem's Background to Transparent to see the Background of the Parent Control
<Canvas Background="Transparent"/>
Rather than a toolbar, think of that as a window.
I would take a look at avalondock.
A transparent canvas:
<Canvas Background="Transparent"
As an aside, this is a couple of steps on from wpf beginner level.
If you take a look at this:
https://imgur.com/4n7vH8k
The user is designing a game scenario. They drag units out the panel on the left ( it's a treeview ) onto the canvas on the right. Only this is not just a plain canvas, it's an itemscontrol with a canvas as the itemspresenter. That allows me to template out the units from a collection of unit view models. It's using the mvvm pattern.
If you've not come across this technique it's a bit strange. Here's a couple of samples to take a look at which templates out different viewmodels into different UI objects. https://1drv.ms/u/s!AmPvL3r385QhgooJ94uO6PopIDs4lQ
https://1drv.ms/u/s!AmPvL3r385QhgooLcGrZOSwFswa-Dg
The datatype is used to decide what you get in the view for what viewmodel.
You have a bit of a complication in that you decided you want a dockable panel usable in multiple windows. Maybe that's not a must have.
Drag drop in my app isn't actually drag drop and relies on an odd aspect of a canvas. They don't clip, so you can add something to a canvas but have it positioned off the canvas.
As you start dragging a unit, it's viewmodel is added to the collection bound to my units itemscontrol. That templates it into the canvas as a piece. I work out the location compared to the canvas, so it'll have a negative X aspect which I bind to Canvas.Left.
Each unit is inside a thumb. A thumb is the rectangle you drag up and down on or side to side on a slider. They are designed for dragging. This way dragging is smooth and I can easily have a unit under the cursor that's being dragged.

Is it possible to rotate a picture box without C# code on the Form Designer or change shape of picture box border?

I am very new to C# and WinForms. I am trying to create a segmented display where certain segments turn on and off (Using Microsoft Visual Studio 2015).
Right now I am placing picture boxes with segments I cropped and removed the background on in GIMP and it works fine so long as the segments are far enough away from each other, or are perfectly square.
When they overlap, with setting the picture box background transparent, the picture box is transparent straight through another picture box and just shows the background of the form window where the rectangular picture box is covering.
I tried two different things:
Changing default rectangular shape of picture box to any shape I can draw; not really sure how to do it and i don't think it is possible
Adding a bunch of picture boxes with a dark black picture and then rotating them and moving them to the correct position and turning them on when the particular segment comes on to cover up the problem. However, I don't think I can, or know how to just rotate an entire picture box when I am placing it? I have seen some code online on rotating picture boxes in C# but I am not sure how to implement it. I feel like with anything else there has to be a rotate option I am just missing.
Attached is a picture of the problem, notice how I sent the segment (line) to the back and the SMS quote image to the front. The dotted lines are the picture boxes:
You can use a WPF project to accomplish what you want. It is much more flexible than WinForms. Plus it supports true transparency. It does have a bit of a learning curve, but if you're just starting out, I think you would be better served to start with WPF.
You can rotate an Image (PictureBox) in WPF as follows:
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="467" Width="616">
<Grid>
<Image Source="C:\MyFolder\MyImage.gif">
<Image.LayoutTransform>
<RotateTransform Angle="45" />
</Image.LayoutTransform>
</Image>
</Grid>
</Window>
The winforms designer does not have features for real UX design. It's mainly targeted for designing simple UI for data oriented application. You will not find any advanced features. You can resize the controls, align them, moving between containers.
There are advanced ways, how to change the shape of controls. But it is not available in winforms designer.
The transparency in winforms is fake. Actualy the transparency means "I'll show the background color of my parent". If you want "true transparency" you must draw the other controls as the background image of target control.

WPF Canvas as a math graphing area

In my graphic calculator, I am using canvas as a plane on which graphs of functions are rendered. I have noticed that whenever I input complex functions (I use bezier curves for that, so the more complex the function -> the more points I need to render for the graph to be smooth-looking) it gets quite laggy and overally doesn't perform well.
Which of these solutions are the least computationally costly / thus are the best approach?
1. (My current solution) Using huge Canvas inside a ScrollViewer that limits the view area
Cons I have found:
The whole canvas is rendered, even the non-visible part
Starts to lag when there is more than 50K elements on the canvas
2. Using just Canvas that is not so big, and management of panning / zooming through TransformMatrix
Cons I think there might be (solution not tried):
Won't it be even more laggy when it will have to redraw and recalculate everything dynammically?
3. Some other solutions?
Any help will be greatly appreciated.
If you can avoid it, you really don't want to be using discrete visuals to represent things like charts/graphs; they are very heavy, and are constantly participating in input handling and layout. I would recommend using WPF's drawing/geometry APIs directly. I would suggest implementing a custom control which performs its own rendering (see OnRender). I would also suggest implementing IScrollInfo so you can manage your own scrolling: you will always know the viewport size and position, which gives you the option of invalidating your geometry when scrolling, and then rebuilding only the parts of the graph that are actually in view. That should reduce the overhead significantly.

PictureBox with shadow [duplicate]

I am trying to figure out how to add a full shadow around a borderless form, using WinForms. I am looking at adding a shadow around all four sides of the form.
I have tried using the DropShadow class, although it only adds the shadow to the bottom and right side corners.
I have seen this question asked many times before in my searches but nothing I cam upon had an answer for all four sides.
I am using both C# and VB.net languages in my solution so any help regarding either language would be a big help.
You are going to have to manually draw this. I have done something similar before with a splash screen, I think. You need to decide the offset of the shadow from the client area of the form and either create a container (easier layout wise) to host its constituent controls or redefine its client rectangle programmatically if you need dynamic shadow size, and then draw your border. If memory serves, you will get the best results using alpha blending + lineargradientbrush to fade the shadow transparency out to the edges.

Categories

Resources