Geometry drawing in WPF - wpf

I'm kinda new to all this geometry part, but I can see it gives me the ability to draw basically whatever I want. I can't find a good manual that teaches how to create whatever image I have in my head. I really hoped to find some kinda painter that extracts the data of the geometry for me but no luck so far.
For example, I found this online:
<Geometry x:Key="MagnifierIconGeometry">M44,12 C32,12 22,22 22,34 22,46 32,56 44,56 56,56 66,46 66,34 66,22 56,12 44,12z M44,0 C63,0 78,15 78,34 78,53 63,68 44,68 40,68 36.5,67.5 33,66 L32.5,66 14,90 0,79.5 18,55.5 17,55 C13,49 10,42 10,34 10,15 25,0 44,0z</Geometry>
You can tell by the name what it draws, but I would like to know how to do it myself?
If anyone could point me to a manual/any kind of program that would be fantastic!
Thanks.

To display vector graphics, in this case you can use the Path like this:
<Window.Resources>
<Geometry x:Key="MagnifierIconGeometry">M44,12 C32,12 22,22 22,34 22,46 32,56 44,56 56,56 66,46 66,34 66,22 56,12 44,12z M44,0 C63,0 78,15 78,34 78,53 63,68 44,68 40,68 36.5,67.5 33,66 L32.5,66 14,90 0,79.5 18,55.5 17,55 C13,49 10,42 10,34 10,15 25,0 44,0z</Geometry>
</Window.Resources>
<Grid>
<Path Data="{StaticResource MagnifierIconGeometry}"
Width="30"
Height="30"
Fill="Aqua"
Stretch="Fill" />
</Grid>
Output
More info
For more information you can see this:
MSDN: Shapes and Basic Drawing in WPF Overview
Charles Petzold: Vector Graphics and the WPF Shape Class
Graphics in WPF
Source of vector images
The www.modernuiicons.com contains a huge amount of vector images that you can use in your applications.
Program for working with vector images
To work with vector graphics you can use Microsoft Expression Blend:
MSDN: Drawing overview
Convert SVG to XAML and use it in Silverlight or WPF

Related

Can you set a Canvas the Background of an element in WPF?

Apologies if this has been asked but I can't find the answer. I have a couple of items (Windows, UserControls and DockPanels) that need dynamic backgrounds.
A Canvas object suits my needs well for the dynamic drawing, however, what I can't figure out is how (or even if) I can set a <Canvas> object as the value of a Background for a control object.
Can this be done and if yes, how?
Yes you can do that.
<Window.Background>
<VisualBrush>
<VisualBrush.Visual>
<Rectangle Width="50" Height="50" Fill="Red"></Rectangle><!-- Replace this with a reference to your Canvas-->
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
Code is referenced from this site there is a lot more that you can do with that background as well. Like set clipping etc ...
Note
Because you haven't specified the language you are developing it, I provided answer in the language I use namely C#, I don't use VB.
Dou you want to set the Background property of a control with the "contents" of a Canvas already populated with elements?
If so, yes; it's possible to accomplish this task creating a Brush from your Canvas. To do it, you need the VisualBrush class. In VB.NET, use something like this:
Dim oBrush As New VisualBrush(myCanvas)
myControl.Background = oBrush
Good luck, good code

How to center text around point using xaml

I would like to be able to place the word "hello" centered on a specific point. I need to do this completely in XAML without extra code. Best I can tell, all the text alignment properties/styles in XAML act on text within some bounding canvas or other element.
Since I don't know the length of the text I want to center, I can't center it using my own code.
The reason I need to solve the problem entirely in XAML is that I'm not using WPF to create the XAML, I'm writing it directly to an XML DOM. It will then be loaded into a Silverlight or WPF control for display.
In most graphic languages, including SVG, which is where my code originated, text can be aligned against a "stationary point" without a bounding box.
Any suggestions appreciated
(Yes, I know this question is old.)
The effectiveness of this solution may vary with the version of Silverlight or the .NET Framework you are using, and I haven't tried it with Silverlight for Windows Phone 7. I wrote a version for stand-alone WPF applications, and I wrote another version that also works in Silverlight.
First, the version that works in Silverlight and WPF. Please note that you will need to refactor the code a little bit if you aren't using a Canvas to provide an absolute position for the center of your TextBlock. For example, you may be using a TranslateTransform to position your text.
<Canvas>
<Canvas.Resources>
<ScaleTransform x:Key="transform" ScaleX="-1" ScaleY="-1" />
</Canvas.Resources>
<Grid RenderTransform="{StaticResource transform}" RenderTransformOrigin="-.25 -.25">
<TextBlock RenderTransform="{StaticResource transform}">
Hello!
</TextBlock>
</Grid>
</Canvas>
Second, the version that works only in WPF. It doesn't work in Silverlight because it depends on the presence of the Canvas.Right and Canvas.Bottom attached properties. UniformGrid isn't in Silverlight either, but that code could have been replaced by a regular Grid with 2 star-length rows and columns.
<Canvas>
<UniformGrid Rows="2" Columns="2"
DataContext="{Binding ElementName=textBox1}"
Width="{Binding Path=ActualWidth}"
Height="{Binding Path=ActualHeight}">
<Canvas>
<TextBlock Name="textBox1" Canvas.Right="0" Canvas.Bottom="0">
Hello!
</TextBlock>
</Canvas>
</UniformGrid>
</Canvas>
By the way, there may be more efficient ways to solve this problem available. I am making no guarantees!

WPF performance for large number of elements on the screen

Im currently trying to create a Scene in WPF where I have around 250 controls on my screen and the user can Pan and Zoom in and out of these controls using the mouse.
I have run the WPF Performance Suite tools on the application when there are a large number of these controls on the screen (i.e. when the user has zoomed right out) the FPS drops down to around 15 which is not very good.
Here is the basic outline of the XAML:
<Window>
<Window.Resources>
<ControlTemplate x:Key="LandTemplate" TargetType="{x:Type local:LandControl}">
<Canvas>
<Path Fill="White" Stretch="Fill" Stroke="Black" StrokeThickness="1" Width="55.5" Height="74.687" Data="M0.5,0.5 L55,0.5 L55,74.187 L0.5,74.187 z"/>
<Canvas x:Name="DetailLevelCanvas" Width="24.5" Height="21" Canvas.Left="15.306" Canvas.Top="23.972">
<TextBlock Width="21" Height="14" Text="712" TextWrapping="Wrap" Foreground="Black"/>
<TextBlock Width="17.5" Height="7" Canvas.Left="7" Canvas.Top="14" Text="614m2" TextWrapping="Wrap" FontSize="5.333" Foreground="Black"/>
</Canvas>
</Canvas>
</ControlTemplate>
</Window.Resources>
...
<local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx">
<local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx">
<local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx">
<local:LandControl Width="55.5" Height="74.552" Canvas.Top="xxx" Template=" {StaticResource LandTemplate}" RenderTransformOrigin="0.5,0.5" Canvas.Left="xxx">
... and so on...
</Window>
Ive tried to minimise the details in the control template and I even did a massive find and replace of the controls to just put their raw elements inline instead of using a template, but with no noticeable performance improvements.
I have seen other SO questions about this and people say to do custom drawing, but I dont really see how that make sense when you have to zoom and pan like I do.
If anyone can help out here, that would be great!
Mark
This may sound trite but - There is no free lunch.
I have worked on [this][1] for the past two years. That product consists of 4 browsers whose interfaces are primarily ZUIs. All but the Atlas use Visuals for their graphic rendering and there were a lot of lessons learned and a few deadends.
FrameworkElements are not your friend. The FE engine on a modern GFX card and CPU maxes out at about 500-600 elements, but it depends on their complexity. FE's are about 10x as heavy as Visuals.
Text will significantly impact your framerate. Rendering curves are expensive See [Robby Ingebretsens post][4] for hints on using animated text
Culling is important, but adding/removing from the VisualTree is expensive. Collapsing/Hiding is kind of a compromise.
In WPF 3.5 you have 2 choices - Program down to the Visuals layer or use something like the [Planerator][2] then manipulate the camera to Pan and Zoom but it requires your users have a good gfx card.
In WPF 4.0 things are much better due to something called [Cached Composition][3]. It works for the same reason the Planerator works. The GFX card is rendering your controls to a bitmap and is panning zooming the bitmap.
Using this in 4,0 is easy - Setup .CacheMode for your most expensive FrameworkElements and things will get a lot faster. You also have the ability to control how text is anti-aliased and the scales at which bitmaps will get regenerated (EnableClearType and RenderAtScale)
In my Atlas browser I could display well over 700 pieces of text + simple rectangles without losing interactivity of panning and zooming. Before 4 the map was unusable.
Getting better interactive performance takes time, targets and measurement. Good luck.
[Kael Rowan][5] has an excellent series of articles on a ZoomableCanvas he is working on. It uses a Quadtree and PriorityQueue for implementation and will let you implement semantic zoom.
Update: 8-07-10 Added Text hints and ZoomableCanvas links
[1]: http://globible.com
[2]: https://learn.microsoft.com/en-us/archive/blogs/greg_schechter/
[3]: https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.bitmapcache?redirectedfrom=MSDN&view=net-5.0
[4]: https://web.archive.org/web/20101210104554/http://blog.nerdplusart.com:80/archives/making-the-most-of-silverlight-text-rendering?
[5]: https://learn.microsoft.com/en-us/archive/blogs/kaelr/
You should be able to use custom drawing in combination with Transformations to achieve the zooming and panning you need. You'll probably need to do some basic culling to prevent elements that are not within the viewport from rendering...but the transformation capabilities of WPF are pretty rich, and you should gain a decent amount of performance with it.
Transforms Overview
How to: Scale an Object
How to: Translate an Element

Round window playing movie using WPF

Is it possible with WPF to create a window that has the shape of a circle and uses a playing movie as the background?
To make a non-rectangular window, you need to first do three things.
Set Window.WindowStyle to WindowStyle.None
Set Window.AllowsTransparency to True
Set Window.Background to Transparent (or {x:Null})
Now, your window is completely transparent. You can use the other tips in this thread to paint a piece of media onto the window's geometry.
You should just need to throw something like this in your xaml:
<Ellipse Height="80" Width="80">
<Ellipse.Fill>
<VisualBrush TileMode="None">
<VisualBrush.Visual>
<MediaElement Source="myMovie.wmv" />
</VisualBrush.Visual>
</VisualBrush>
</Ellipse.Fill>
</Ellipse>
Actually making the window round would be more difficult. Have a look at this if you want the window to be round, it should help figure that part out.
HTH
Don't use AllowsTransparency, it has very poor performance and a lot of compatibility problems, go to this link for alternatives:
http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx
EDIT: there is an example there how to use SetWindowRgn to get rounded corners for a rectangular windows, if you pass an ellipse region instead of a rounded-rect region you will get an elliptic window, it's easy to create a region for any shape you can imagine.
you can have a canvas as your parent container (set to transparent) then add a circle with a media brush as it's background. that should do it. :)

What's the best way to display a video with rounded corners in Silverlight?

The MediaElement doesn't support rounded corners (radiusx, radiusy). Should I use a VideoBrush on a Rectangle with rounded corners?
Yeah - In a way you're both asking and answering the question yourself... But that is one of the two options I can think of. The reasons that might be a problem is that you lose some of the features/control you get from the MediaElement control. Another option is to do this:
Add your MediaElement to your page.
Draw a Rectangle on top of it and set wanted corner radius
Right click the rectangle in Blend and choose "Create Clipping Path"
Apply the clipping path to your MediaElement
That way you're still using a MediaElement control, but you can "clip" away what ever you want to get the desired rounded effect.
This example shows a clipped MediaElement. I know it's not easy to picture the vector path, but if you open it open in Blend you will see a rounded MediaElement.
<MediaElement
Height="132" Width="176" Source="Egypt2007.wmv"
Clip="M0.5,24.5 C0.5,11.245166 11.245166,0.5 24.5,0.5 L151.5,0.5
C164.75484,0.5 175.5,11.245166 175.5,24.5 L175.5,107.5 C175.5,
120.75484 164.75484,131.5 151.5,131.5 L24.5,131.5 C11.245166,
131.5 0.5,120.75484 0.5,107.5 z"/>
Using a rounded rectangle and a VideoBrush doesn't lose you any features/control over using a displayed MediaElement - since the element has to be in the Xaml anyway, you can control it using the usual Play/Pause/Stop methods, except that the playback happens in your rectangle. Using a clip region is a little unwieldy because it's harder to resize the region. A Rectangle is better because you have flexibility of layout.
<MediaElement x:Name="myElement" Source="clip.wmv" Visibility="Collapsed"/>
<Rectangle RadiusX="10" RadiusY="10" Width="640" Height="480">
<Rectangle.Fill>
<VideoBrush Source="myElement" Stretch="Uniform"/>
</Rectangle.Fill>
<Rectangle/>
The clip path with give you "hard" edges - you could also use an OpacityMask as well (though I imagine this requires much more processing power).
Try this
<Border CornerRadius="8" BorderBrush="Black" Background="Black" BorderThickness="3">
<MediaElement HorizontalAlignment="Center" VerticalAlignment="Top" Stretch="Fill" x:Name="Player" Source="/Assets/Videos/x.mp3" />
</Border>

Resources