Partager via


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>