分类存档: Windows

WPF Linked resources导致”cannot locate resource”错误

【注意】这个问题在Visual Stuido2010(.Net Framework4.0)中已经修复,在VS2010中Source应该改为全路径,否则会导致运行时资源无法定位。

错误描述:

当我们向WPF项目中添加文件(Add items)时,我们可以选择”Add As Link”,这样做的目的是:我们可以在多个项目之间共享同一个文件(比如一个被多个项目引用的图标文件,或者项目间共享的资源等)。

但是,如果引用的对象位于项目的某个目录中,我们将无法用通常的URI语法来加载资源,比如下图中我们将以链接形式添加Info.xml文件到项目中(比如我们将它添加到目录Data下):

当我们希望在XAML文档中引用该资源时:
Source="pack://application:,,,/AssemblyName;component/Data/Info.xml"
以上代码在运行时会报错(cannot locate resource ‘Data/Info.xml’)

如果不是Add As Link方式而是直接添加以上资源的话,上面的代码是没有问题的,可是由于微软对Link文件的路径处理和普通项目文件有一定的区别,所以导致运行时无法正确加载资源文件。

解决方法:
Link的资源在VS2008下,默认编译完成后,是放在根目录下的,而不是我们设置的Data目录下:

修改为以下路径后可以解决问题:
Source="pack://application:,,,/AssemblyName;component/Info.xml"

引用资源:

关于该Bug的详细描述和微软官方回复:

http://connect.microsoft.com/VisualStudio/feedback/details/512027/linked-files-in-folders-are-not-output-correctly-in-wpf

其他参考的问题解决方法:

http://stackoverflow.com/questions/428609/how-can-i-address-hopefully-in-xaml-a-linked-resource-properly-in-wpf

http://devblog.ailon.org/devblog/post/2010/01/13/Writing-WPFSilverlight-compatible-code-Part-6-Adding-XAML-files-as-links.aspx

How to set WPF window position according to DPI settings

Vista中当DPI设置改变的时候,屏幕的尺寸会改变,如果WPF窗口的位置是具体像素值偏移的,就需要根据当前的DPI配置进行相应的调整。

可以得到的系统参数(System Parameters we can get from WPF):

System.Windows.Forms.SystemInformation.WorkingArea (Width, Height)

Use WorkingArea to determine the bounds of the screen that can be used by applications. The working area is the portion of the screen not hidden by the operating system tray and other top-level windows that are docked to the Windows desktop.

工作区域的宽度、高度(高度不包括任务栏)

System.Windows.SystemParameters (PrimaryScreenWidth, PrimaryScreenHeight)

Gets a value that indicates the screen width/height, in pixels, of the primary display monitor.

屏幕区域的宽度、高度

网上搜罗来的解决办法:

Solution 1:

Get the current DPI value in WPF, and scale the width/height in pixels.

在WPF程序中取得当前DPI的设置,计算出像素宽度/高度的缩放数值

PresentationSource source = PresentationSource.FromVisual(this);

if (source != null)
{
dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11;

dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22;
}

Solution 2:

Using System.Windows.SystemParameters (PrimaryScreenWidth, PrimaryScreenHeight)

注意PrimaryScreenWidth, PrimaryScreenHeight这两个参数得到的像素数值本来就是经过DPI换算过的,但是请注意PrimaryScreenHeight的高度包括TaskBar。

WPF textblock Run之间的自动填充的空格

代码:
<TextBlock>
<Run Foreground=”你确定要删除” Text=”Text”/>
<Run Foreground=”配置名称” Text=”Block”/>
<Run Text=”?” />
</TextBlock>

编译后,“?”前面会自动加上一个空格。这个空格是由于XAML(其实也就是XML)解析的时候的特殊空白字符处理规则(special
whitespace handling rules
)造成的。
去掉这个空格的最简单方法是:把上面的三个Run紧挨着写在同一行上:
<TextBlock>
<Run Foreground=”你确定要删除” Text=”Text”/><Run Foreground=”配置名称” Text=”Block”/><Run Text=”?” />
</TextBlock>

VS2008:error C2259 cannot instantiate abstract class

Visual Studio2008编译错误error C2259 cannot instantiate abstract class

经过检查,发现源代码中确实已经派生了虚函数,派生的虚函数源文件也正常编译。

最后在微软的官方网站上找到了答案(可能只是error C2259其中一种可能的原因,供参考):

This behavior is by design with VS 2005. The root cause is because wchar_t is a different type than unsigned short though in prior versions of Visual C++, the compiler considered them to be the same type. In this sample code, the type library uses unsigned short but the C++ source files use wchar_t. So the types don’t match therefore the functions that contain these types in their signatures don’t override the interface.

在VS 2005/VS2008中,wchar_t和unsigned short是不同的类型,尽管在之前的Visual C++版本中编译器将两者视为了相同的类型。由于参数类型的不匹配导致编译器无法正确地识别或编译重载的接口。

To continue working with this sample, either correct the type mismatch or use the /Zc:wchar_t- compiler switch to force the compiler to consider wchar_t the same type as unsigned short.
In the VS 2005 project property properties, under the C/C++ node, select Language. Then change “Treat wchar_t as Built-In Type” from “Yes” to “No”.
解决办法:使用/Zc:wchar_t-编译选项强制让编译器将wchar_t 和 unsigned short视为相同类型。或者在VS 2005/VS2008中,将项目属性中将”Treat wchar_t as Built-In Type”一项设置为”No”.

微软相关链接地址:

http://connect.microsoft.com/VisualStudio/feedback/details/101072/error-c2259-cannot-instantiate-abstract-class#

Visual Studio LNK2005 error

环境:  Visual Studio 2008 C++

编译错误: error LNK2005: _DllMain@12 already defined …

The CRT libraries use weak external linkage for the new, delete, and DllMain functions. The MFC libraries also contain new, delete, and DllMain functions. These functions require the MFC libraries to be linked before the CRT library is linked.

微软的支持文档指出,MFC库的链接必须在CRT库之前,而解决方法有2种:

1. 强制连接器以正确的顺序链接,具体方法见下面的微软链接。

2. 在Linker标签页中,找到Command Line属性,并添加附加选项: /verbose:lib,重新编译工程,工程会列出详细的库清单,根据输出的内容来修正有问题的组件。

其中如果使用的是MFC库,确保每一个工程文件都包含头文件 #include <Stdafx.h>。

http://support.microsoft.com/kb/148652

Canonical URL by SEO No Duplicate WordPress Plugin