我能否在WPF中动态创建图标?

4

由于我之前的问题没有得到解决,我想知道,在WPF上有没有办法可以动态创建图标?


“on the fly” 是什么意思? - Emond
他可能是指使用XAML(很可能是数据驱动的)生成图像,并将其保存为位图。 - Joel Martinez
我的意思是按需求,比如说我想在托盘图标中显示进度状态,而不是显示工具提示,我想在图标顶部显示一个带有状态显示的图标。 - iraSenthil
5个回答

1

你不需要WPF。

使用GDI+ (System.Drawing.dll),你可以创建一个16x16的Bitmap,然后调用Icon.FromHandle(bitmap.GetHicon())


你是说我不能在WPF中做到吗? - iraSenthil
不,我是说你可以在WinForms中做到这一点。 - SLaks
1
为什么要在WPF/GDI互操作中额外依赖System.Drawing并付出昂贵的代价,如果你可以只在WPF中本地实现它呢? - bitbonk
@bitbonk:在他最初的问题中,听起来他想要GDI+。WPF没有NotifyIcon,所以他无论如何都需要GDI+和WinForms。 - SLaks
@SLaks,我正在寻找WPF解决方案。 - iraSenthil
哎呀,我没看到他实际上想要一个NotityIcon。无论如何,这将涉及到win32互操作,我想。 - bitbonk

0

您可以在这里这里找到一种方法,用于在可写位图上呈现文本


0

@iraSenthil 这里有一个逐像素绘图的方法 http://tipsandtricks.runicsoft.com/CSharp/WpfPixelDrawing.html - Code0987
@Neeraj 我该如何添加文本和图片? - iraSenthil

0

这就是我最终做的事情,我并不完全理解其中的细节,如果你发现有任何可以改进的地方,请评论告诉我。感谢所有的答案和评论。

 public static ImageSource GetIconWithText(int digit)
 {
     BitmapImage myBitmapImage = new BitmapImage(new Uri(@"Images\PomoDomo.ico", 
         UriKind.RelativeOrAbsolute));

     DrawingVisual drawingVisual = new DrawingVisual();

     using (DrawingContext drawingContext = drawingVisual.RenderOpen())
     {
         // Draw image
         drawingContext.DrawImage(myBitmapImage, new Rect(0, 0, myBitmapImage.Width, 
             myBitmapImage.Height));

         var typeFace = new Typeface(new FontFamily("Verdana"), FontStyles.Normal, 
             FontWeights.ExtraBold, FontStretches.UltraCondensed);
         var formatedText = new FormattedText(digit.ToString(),
               CultureInfo.InvariantCulture,
               FlowDirection.LeftToRight,
               typeFace,
               40, 
               System.Windows.Media.Brushes.White);

         //Center the text on Image
         int pointY = (int)(myBitmapImage.Height - formatedText.Height) / 2;
         int pointX = (int)(myBitmapImage.Width - formatedText.Width) / 2;

         drawingContext.DrawText(formatedText, new Point(pointX, pointY));
     }

     RenderTargetBitmap finalBitmap = new RenderTargetBitmap((int)myBitmapImage.Width, 
         (int)myBitmapImage.Height, myBitmapImage.DpiX, myBitmapImage.DpiY, 
         PixelFormats.Pbgra32);
     finalBitmap.Render(drawingVisual);
     return finalBitmap;
 }

 private static void SaveImage(RenderTargetBitmap returnBitmap, string pngFileName)
 {
     string fileName = string.Format("{0}.png", pngFileName)
     PngBitmapEncoder image = new PngBitmapEncoder();
     image.Frames.Add(BitmapFrame.Create(returnBitmap));
     using (Stream fs = File.Create(fileName))
     {
         image.Save(fs);
     }
 }

0

您可以使用任务栏图标进度条...您肯定已经看到,大多数应用程序在执行任何扫描或进度操作时,都会在图标上显示进度动作。

请在包含图标的主窗体中执行此操作。

<Window x:Class="CCTrayHelper.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
    Icon="/CCTrayHelper;component/Images/CCTrayHelperIcon.png">

<Window.TaskbarItemInfo>
    <TaskbarItemInfo />
</Window.TaskbarItemInfo>

从代码后台触发它

 private void OnProgress(object sender, EventArgs args)
    {
        Dispatcher.Invoke(DispatcherPriority.Send, (Action)delegate() { TaskbarItemInfo.ProgressState = TaskbarItemProgressState.None; });
        // Use here your progress type
    }

我需要托盘图标的状态,无论如何感谢您的建议。 - iraSenthil
是的!它只适用于Windows 7…… @iraSenthil,你的意思是像Messenger图标一样,如果用户忙或不可用,则在图标上显示其他动画或图像……对吗? - PawanS
更接近了,但我想添加一些文本而不是一些有限的图标。 - iraSenthil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接