How would I convert an Ellipse with a fill to an ImageDrawing in C#

380 views Asked by At

I have created an Ellipse. How would I then convert that Ellipse to a ImageDrawing?

Essentially what I am trying to do is take 3 ImageDrawings, (TopDrawing a MiddleDrawing and BottomDrawing),

Stack them on top of eachother to create a Single drawing. But I alsow what the user to be able to rotate the middle drawing while the other layers, namely the bottom and top, stay still.

I have to do this in code and not XAML because the entity is database driven.

The way that I got the 3 images to stack was by using a DrawingGroup.
enter image description here

The problem is that I cant rotate the middle drawing to lets say 23.

I hope I explained this clearly. It was suggested that I try using Ellipses but I need to convert them to a ImageDrawing.

Any help would be great.

1

There are 1 answers

2
Kelly Barnard On

Why can't you use XAML? here is a gauge I whipped up that is very scale-able the can be bound to any data you want.

XAML:

 <UserControl x:Class="clock.ctlGauge"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:clock"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
    <Viewbox>
        <Grid Height="300" Width="300">
            <Ellipse Fill="Yellow" Stroke="Black" StrokeThickness="3" />
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="55"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="125"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="154"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="183"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="212"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="241"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="270"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="299"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="328"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="357"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <Line Stroke="Black" StrokeThickness="3" X1="150" X2="150" Y1="5" Y2="30" RenderTransformOrigin="0.5,0.5">
                <Line.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="26"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Line.RenderTransform>
            </Line>
            <TextBlock x:Name="textBlock" Height="38.436" Margin="134.688,23.438,140,0" TextWrapping="Wrap" Text="8" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold"/>
            <TextBlock x:Name="textBlock_Copy" Height="38.436" Margin="0,30.221,89.375,0" TextWrapping="Wrap" Text="9" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy1" Height="38.436" Margin="0,69.376,50.938,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="34.687"><Run Text="10"/><LineBreak/><Run/></TextBlock>
            <TextBlock x:Name="textBlock_Copy2" Height="38.436" Margin="0,0,42.5,72.188" TextWrapping="Wrap" Text="0" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy3" Height="38.435" Margin="0,0,89.375,38.439" TextWrapping="Wrap" Text="1" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Right" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy4" Height="38.436" Margin="134.688,0,140,31.656" TextWrapping="Wrap" Text="2" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold"/>
            <TextBlock x:Name="textBlock_Copy5" Height="38.436" Margin="85.001,0,0,46.876" TextWrapping="Wrap" Text="3" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy6" Height="38.436" Margin="47.5,0,0,87.188" TextWrapping="Wrap" Text="4" VerticalAlignment="Bottom" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy7" Margin="35.313,128.347,0,133.217" TextWrapping="Wrap" Text="5" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy8" Height="38.436" Margin="47.5,76.159,0,0" TextWrapping="Wrap" Text="6" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
            <TextBlock x:Name="textBlock_Copy9" Height="38.436" Margin="85.001,44.506,0,0" TextWrapping="Wrap" Text="7" VerticalAlignment="Top" FontSize="29.333" FontWeight="Bold" HorizontalAlignment="Left" Width="25.312"/>
            <Polygon x:Name="MainPointer" Fill="Red" RenderTransformOrigin="0.5,0.5">
                <Polygon.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="{Binding MainPointerAngle}"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Polygon.RenderTransform>
                <Polygon.Points>
                    <Point X="145" Y="150" />
                    <Point X="155" Y="150" />
                    <Point X="150" Y ="0" />
                </Polygon.Points>
            </Polygon>
            <Polygon x:Name="MaxPoint" RenderTransformOrigin="0.5,0.5" Stroke="Black" StrokeThickness="1">
                <Polygon.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="{Binding MaxPointAngle}"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Polygon.RenderTransform>
                <Polygon.Points>
                    <Point X="145" Y="3" />
                    <Point X="155" Y="3" />
                    <Point X="155" Y ="35" />
                    <Point X="150" Y="40" />
                    <Point X="145" Y="35" />
                </Polygon.Points>
                <Polygon.Fill>
                    <LinearGradientBrush EndPoint="1.0,0" StartPoint="0,0">
                        <GradientStop Color="#FFD60000" Offset="0"/>
                        <GradientStop Color="#FFD60000" Offset="1"/>
                        <GradientStop Color="#FF720000" Offset="0.5"/>
                        <GradientStop Color="#FFA00000" Offset="0.4"/>
                        <GradientStop Color="#FFA00000" Offset="0.6"/>
                    </LinearGradientBrush>
                </Polygon.Fill>
            </Polygon>
            <Ellipse HorizontalAlignment="Center" VerticalAlignment="Center" Width="20" Height="20" >
                <Ellipse.Fill>
                    <LinearGradientBrush EndPoint="0.981,0.547" StartPoint="0.008,0.547">
                        <GradientStop Color="Black" Offset="0"/>
                        <GradientStop Color="#FFB9B9B9" Offset="1"/>
                    </LinearGradientBrush>
                </Ellipse.Fill>

            </Ellipse>
        </Grid>
    </Viewbox>

</UserControl>

Code Behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 clock
{
    /// <summary>
    /// Interaction logic for ctlClock.xaml
    /// </summary>
    public partial class ctlGauge : UserControl
    {
        public static DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(MaxValue_Changed)));

        public double MaxValue
        {
            get { return (double)GetValue(MaxValueProperty); }
            set { SetValue(MaxValueProperty, value); }
        }


        private static void MaxValue_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
        {
            ctlGauge thisClass = (ctlGauge)o;
            thisClass.SetMaxValue();
        }

        private void SetMaxValue()
        {
            MaxPointAngle = GetValueAngle(MaxValue);
        }

        public static DependencyProperty CurrentValueProperty = DependencyProperty.Register("CurrentValue", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(CurrentValue_Changed)));

        public double CurrentValue
        {
            get { return (double)GetValue(CurrentValueProperty); }
            set { SetValue(CurrentValueProperty, value); }
        }


        private static void CurrentValue_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
        {
            ctlGauge thisClass = (ctlGauge)o;
            thisClass.SetCurrentValue();
        }

        private void SetCurrentValue()
        {
            MainPointerAngle = GetValueAngle(CurrentValue);
        }

        public static DependencyProperty MainPointerAngleProperty = DependencyProperty.Register("MainPointerAngle", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(MainPointerAngle_Changed)));

        public static DependencyProperty MaxPointAngleProperty = DependencyProperty.Register("MaxPointAngle", typeof(double), typeof(ctlGauge), new FrameworkPropertyMetadata(new PropertyChangedCallback(MaxPointAngle_Changed)));

        public double MaxPointAngle
        {
            get { return (double)GetValue(MaxPointAngleProperty); }
            set { SetValue(MaxPointAngleProperty, value); }
        }


        private static void MaxPointAngle_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
        {
            ctlGauge thisClass = (ctlGauge)o;
            thisClass.SetMaxPointAngle();
        }

        private void SetMaxPointAngle()
        {
            //Put Instance MaxPointAngle Property Changed code here
        }

        public double MainPointerAngle
        {
            get { return (double)GetValue(MainPointerAngleProperty); }
            set { SetValue(MainPointerAngleProperty, value); }
        }


        private static void MainPointerAngle_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)
        {
            ctlGauge thisClass = (ctlGauge)o;
            thisClass.SetMainPointerAngle();
        }

        private void SetMainPointerAngle()
        {
            //Put Instance MainPointerAngle Property Changed code here
        }

        public ctlGauge()
        {
            InitializeComponent();
            SetCurrentValue();
            SetMaxValue();
        }

        private double GetValueAngle(double value)
        {
            double dAngle = 125 + (value * 29);
            if (dAngle > 360)
            {
                dAngle -= 360;
                if (dAngle > 56)
                    dAngle = 56;
            }
            else if (dAngle < 124)
                dAngle = 124;

            return dAngle;
        }
    }
}

Test Window:

<Window x:Class="clock.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:clock"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <local:ctlGauge CurrentValue="{Binding ElementName=sldPointerAngle, Path=Value}" MaxValue="{Binding ElementName=sldMaxAngle, Path=Value}" Grid.ColumnSpan="3" />
        <TextBlock Text="Pointer Value:" HorizontalAlignment="Right" Grid.Row="1" />
        <Slider Name="sldPointerAngle" Grid.Row="1" Grid.Column="1" Minimum="-1" Maximum="11" Value="0" />
        <TextBlock Grid.Column="2" Grid.Row="1" Width="100" Text="{Binding ElementName=sldPointerAngle, Path=Value}" />

        <TextBlock Text="Max Value:" HorizontalAlignment="Right" Grid.Row="2" />
        <Slider Name="sldMaxAngle" Grid.Row="2" Minimum="0" Grid.Column="1" Maximum="10" Value="9" />
        <TextBlock Grid.Column="2" Grid.Row="2" Width="100" Text="{Binding ElementName=sldMaxAngle, Path=Value}" />
    </Grid>
</Window>

You can of course spruce up the gauge a bit.

Test Gauge Output

Edit: Using Images instead of polygones:

<UserControl x:Class="clock.ctlGauge"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:clock"
             mc:Ignorable="d" 
             d:DesignHeight="256" d:DesignWidth="256" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
    <Viewbox>
        <Grid Height="256" Width="256">
            <Image Name="imgBack" Source="images/Yellowback.png" />
            <Image Name="imgBigPointer" Source="images/Pointer1.png" RenderTransformOrigin="0.5,0.5">
                <Image.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="{Binding MainPointerAngle}"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
            <Image Name="imgSmallPointer" Source="images/Pointer2.png" RenderTransformOrigin="0.5,0.5">
                <Image.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="{Binding MaxPointAngle}"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Image.RenderTransform>
            </Image>
            <Image Name="imgBorder" Source="images/CircleBorder.png" />
            <Image Name="imgCenterCover" Source="images/CenterCover.png" />
        </Grid>
    </Viewbox>

</UserControl>

In Code Behind: imgBack.Source = new BitmapImage(new Uri(@"c:\yourfilelocation"));