Ulf Honkanen
Ulf Honkanen

Reputation: 119

Programmatically setting the icon size

On WPF I am creating a menu item dynamically at run time.

I set the icon from a StreamGeometry that's stored on a ResourceDictionary. Everything works OK but: how do I set the size of the icon?

MenuItem menExit = new MenuItem();
menExit.Header = "Exit"; // will be changedlater
menExit.Command = UICommands.CmdExit;
menExit.CommandBindings.Add(new CommandBinding(UICommands.CmdExit, CmdExitExecute, CmdExitCanExecute));
menExit.Icon = (StreamGeometry)FindResource("ImgExit");

//SET THE SIZE HERE????????
// Eventually, how do I set the fill color?

menu.Items.Add(menExit);

Note, I am doing all this at run time and not in xalm

Upvotes: 0

Views: 684

Answers (2)

ArchAngel
ArchAngel

Reputation: 644

You can always try this:

/// <summary>
/// Convert Geometry to ImageSource, Draws the Geometry on a bitmap surface and centers it.
/// </summary>
/// <param name="geometry"></param>
/// <param name="TargetSize"></param>
/// <returns></returns>
ImageSource Geometry_To_ImageSource(Geometry geometry, int TargetSize)
{
   var rect = geometry.GetRenderBounds(new Pen(Brushes.Black, 0));

   var bigger = rect.Width > rect.Height ? rect.Width : rect.Height;
   var scale = TargetSize / bigger;

   Geometry scaledGeometry = Geometry.Combine(geometry, geometry, GeometryCombineMode.Intersect, new ScaleTransform(scale, scale));
   rect = scaledGeometry.GetRenderBounds(new Pen(Brushes.Black, 0));

   Geometry transformedGeometry = Geometry.Combine(scaledGeometry, scaledGeometry, GeometryCombineMode.Intersect, new TranslateTransform(((TargetSize - rect.Width) / 2) - rect.Left, ((TargetSize - rect.Height) / 2) - rect.Top));

   RenderTargetBitmap bmp = new RenderTargetBitmap(TargetSize, TargetSize, 96, 96, PixelFormats.Pbgra32);

   DrawingVisual viz = new DrawingVisual();
   using (DrawingContext dc = viz.RenderOpen())
   {
      dc.DrawGeometry(Brushes.Black, null, transformedGeometry);
   }

   bmp.Render(viz);

   var mem = new MemoryStream();
   PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
   pngEncoder.Frames.Add(BitmapFrame.Create(bmp));
   pngEncoder.Save(mem);
   var itm = GetImg(mem);
   return itm;
}

BitmapImage GetImg(MemoryStream ms)
{
   var bmp = new BitmapImage();    
   bmp.BeginInit();
   bmp.StreamSource = ms;
   bmp.EndInit();

   return bmp;
}

Upvotes: 0

Amaury Lev&#233;
Amaury Lev&#233;

Reputation: 1512

I suggest you to create a path on which you can specify Height, Width and Fill and set your StreamGeometry as the Data of the path. Then put this Path as the icon of the MenuItem.

var path = new Path
{
    Height = 20,
    Width = 20,
    Fill = new SolidColorBrush(Colors.Blue),
    Data = (StreamGeometry) FindResource("ImgExit")
};
menExit.Icon = path;

Upvotes: 2

Related Questions