Its easy to Create your own FrameWorkElement in WPF
Sometimes you want to have very fine control of how your application looks and behaves. Other times, you just want to draw something on your UI.
It’s pretty easy to create your own control class and put instances of it on your form.
The sample below create a new class MyFrameworkElement which allows you to draw whatever you want in a control. It handles the SizeChanged event by recording the new size and invalidating the Visual, which causes a rendering to occur. The actual drawing is of a rectangle and an ellipse and some text. Resizing the Window resize the shapes as well. Try modifying the code and putting the MyFrameworkElement into another control, like a ListView, or even a menu!
Start Visual Studio 2010 or 2012.
File->New->Project->C# or VB Windows WPF Application.
Paste in the VB or C# code below (For C#, you might have to modify the Namespace to match the name of your project)
<VB Code>
Class MainWindow
Private Sub Window_Loaded(ByVal sender As System.Object,
ByVal e As System.Windows.RoutedEventArgs
) Handles MyBase.Loaded
Try
Dim brush = Brushes.AliceBlue
Me.Content = New MyFrameWorkElement
Catch ex As Exception
Me.Content = ex.ToString
End Try
End Sub
Public Class MyFrameWorkElement
Inherits FrameworkElement
Private _size As Size
Sub Size_Changed(ByVal o As Object,
ByVal e As SizeChangedEventArgs
) Handles Me.SizeChanged
_size = e.NewSize
Me.InvalidateVisual()
End Sub
Protected Overrides Sub OnRender(
ByVal drawingContext As System.Windows.Media.DrawingContext
)
MyBase.OnRender(drawingContext)
drawingContext.DrawRectangle(
Brushes.Blue,
New Pen(Brushes.Red, 2),
New Rect(1, 1, _size.Width / 2, _size.Height / 2))
drawingContext.DrawEllipse(
Brushes.Green,
New Pen(Brushes.Yellow, 2),
center:=New Point(_size.Width / 2, _size.Height / 2),
radiusX:=_size.Width / 4,
radiusY:=_size.Height / 4)
Dim txt = New FormattedText(
"Foobar",
System.Globalization.CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
New Typeface("Courier new"),
21,
Brushes.Red)
drawingContext.DrawText(txt,
New Point(_size.Width / 2, _size.Height / 2)
)
End Sub
End Class
End Class
</VB Code>
<C# Code>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Content = new MyFrameWorkElement();
}
}
public class MyFrameWorkElement : FrameworkElement
{
Size _size;
public MyFrameWorkElement()
{
this.SizeChanged += (o, e) =>
{
_size = e.NewSize;
this.InvalidateVisual(); // cause a render
};
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
drawingContext.DrawRectangle(
Brushes.Blue,
new Pen(Brushes.Red, 2),
new Rect(1, 1, _size.Width / 2, _size.Height / 2));
drawingContext.DrawEllipse(
Brushes.Green,
new Pen(Brushes.Yellow, 2),
center: new Point(_size.Width / 2, _size.Height / 2),
radiusX: _size.Width / 4,
radiusY: _size.Height / 4);
var txt = new FormattedText(
"Foobar",
System.Globalization.CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Courier new"),
21,
Brushes.Red);
drawingContext.DrawText(txt,
new Point(_size.Width / 2, _size.Height / 2)
);
}
}
}
</C# Code>