在WPF XAML窗口上添加图标会导致VS2012出错/崩溃。

3

当为XAML窗口指定图标时,我发现WPF XAML中存在一个错误,尝试运行程序会在该行上生成错误消息:

 System.Windows.Application.LoadComponent(Me, resourceLocater)

XamlParseException发生

'System.Windows.Baml2006.TypeConverterMarkupExtension'上的Provide value引发了异常。'行号'5'和行位置'100'。

我已经将图标设置为始终创建,并将其添加到复制到输出目录,但没有成功。
我将图标从Resource更改为EmbeddedResource,但也没有成功。
我将它添加到项目的Resources中,但仍然没有成功。
我已经100%确认文件及其位置正确。
窗口的XAML是正确的,名称是正确的,路径也是正确的。

Icon="Resources/VisualizerIcon.ico" 

在线论坛建议将“复制到输出目录”设置为解决方案,但是在构建解决方案后,只有文件夹被复制过去了(尽管我明确设置了要复制ICO文件)。
有人能帮忙吗?

注意:我清理了项目,ICO文件现在显示在BIN文件夹中,但仍然出现与上述相同的错误。 - MC9000
你看过这个吗:msdn页面 - Noctis
1
我之前不太确定如何使用那里的信息,但是我发现,如果我给窗口命名(之前没有命名),并在_Loaded事件中分配图标,它就可以正常工作了。问题在于图标属性正在寻找BitmapSource,而不是Bitmap。因此,我必须将Bitmap转换为Bitmapsource才能使用它。 - MC9000
5个回答

8

您只需要在属性窗口中将实际图像/图标的构建操作设置为“资源”即可。

enter image description here

我知道这是一个旧帖子,只是想分享一个虚拟错误。


没错!为什么资源没有设置为资源来构建呢?WPF的方式是怎样的呢? - DrMarbuse

4
您可以使用项目设置进行设置(右键单击您的项目,然后选择“属性”)。
如下截图所示: enter image description here 我发现这样更简单,不需要编写代码,它也能正常工作...

那是我尝试的第一件事情(我使用了你上面展示的技巧添加了ico和另一个嵌入式资源),但它仍然以相同的错误消息崩溃。真费解。 - MC9000
很奇怪...你确定类型没问题吗?并且做了通常的清理、重建,祈求木鸡神灵让它能够正常构建? - Noctis
可能有些东西我错过了,这是我第一次涉足WPF。 - MC9000
欢迎来到 WPF 世界!一旦你把马车赶往正确的方向,这将会是一段愉快的旅程。现在来试试一个新的解决方案吧,只需加入一个标签,并尝试通过设置来设定图标。如果可以,那么你的项目可能出了些问题;如果不行,那就太奇怪了。 - Noctis

1

只需将资源编译属性设置为“Resources”,然后使用即可。

    <Image width="80" Height="80" Source="Resources/my_image.png"/>

或窗口图标
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyApplication" x:Name="Main_Window" x:Class="MainWindow"
    Title="MainWindow" Height="600" Width="800" Icon="Resources/icon.ico">

这仅适用于直接引用ICO文件的情况,如果您将其替换为对<Image>资源进行{StaticResource}绑定,您将会收到一个异常,如“System.Windows.Image'不适用于属性'Icon'。” - Tim Sylvester

1
尝试检查内部异常。如果调用站点看起来像这样:

在 System.Windows.Media.Imaging.BitmapSource.CriticalCopyPixels(System.Windows.Int32Rect, IntPtr, Int32, Int32) 处 在 System.Windows.Media.Imaging.BitmapSource.CriticalCopyPixels(System.Windows.Int32Rect, System.Array, Int32, Int32) 处 在 System.Windows.Media.Imaging.BitmapSource.CopyPixels(System.Windows.Int32Rect, System.Array, Int32, Int32) 处 在 System.Windows.Media.Imaging.BitmapSource.CopyPixels(System.Array, Int32, Int32) 处 在 MS.Internal.AppModel.IconHelper.CreateIconHandleFromBitmapFrame(System.Windows.Media.Imaging.BitmapFrame) 处 在 MS.Internal.AppModel.IconHelper.CreateIconHandleFromImageSource(System.Windows.Media.ImageSource, System.Windows.Size) 处 在 MS.Internal.AppModel.IconHelper.GetIconHandlesFromImageSource(System.Windows.Media.ImageSource, IconHandle ByRef, IconHandle ByRef) 处 在 System.Windows.Window.UpdateIcon() 处 在 System.Windows.Window.SetupInitialState(Double, Double, Double, Double) 处 在 System.Windows.Window.CreateSourceWindow(Boolean) 处 在 System.Windows.Window.ShowHelper(System.Object) 处 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) 处 在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) 处 在 System.Windows.Threading.DispatcherOperation.InvokeImpl() 处 在 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 处 在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) 处 在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) 处 在 MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object) 处 在 System.Windows.Threading.DispatcherOperation.Invoke() 处 在 System.Windows.Threading.Dispatcher.ProcessQueue() 处 在 System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) 处 在 MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef) 处 在 MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object) 处 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32) 处 在 System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate) 处 在 System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32) 处 在 MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr) 处 在 MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef) 处 在 System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame) 处 在 System.Windows.Application.RunDispatcher(System.Object) 处 在 System.Windows.Application.RunInternal(System.Windows.Window) 处 在 ClientLauncher.App.Main() 处

那么您可能会遇到像this这样的错误,但它可能会在更新的操作系统上发生,如Windows 10。我们的一些客户在Windows 10机器上遇到了这种崩溃。

解决方案是简化图标文件,不要让它包含大于64 * 64的框架,或者仅使用PNG作为窗口图标。话虽如此,高分辨率图标仍可用作应用程序图标。


0

这是我想出来的(不够优雅,但是可行)在窗口的加载事件中:

Private Sub TileLayout_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
    Me.winTileLayout.Icon = Bitmap2BitmapSource(My.Resources.VisualizerIcon.ToBitmap)
End Sub

还有辅助函数:

Public Shared Function Bitmap2BitmapSource(bmp As System.Drawing.Bitmap) As BitmapSource
    Dim retval As BitmapSource = Nothing
    Dim hBitmap As IntPtr = bmp.GetHbitmap()
    Try
        retval = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions())
    Catch ex As Win32Exception
        retval = Nothing
    Finally
        DeleteObject(hBitmap)
    End Try
    Return retval
End Function

删除对象代码:

<System.Runtime.InteropServices.DllImport("gdi32.dll")> _
Public Shared Function DeleteObject(hObject As IntPtr) As Boolean
End Function

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