XamlParseException in app.xaml resource strings

2019-07-17 21:35发布

问题:

I have the following code in App.xaml:

<Application x:Class="PcgTools.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:local="clr-namespace:PcgTools.ViewModels" 
         xmlns:res="clr-namespace:PcgTools.Resources"
         StartupUri="MainWindow.xaml"
         Startup="Application_Startup">
    <Application.Resources>
        <ResourceDictionary>
            ...
            <res:Strings x:Key="LocStrings"/>
        </ResourceDictionary> 
    </Application.Resources>
</Application>

(The ... are some lines which I removed to make the example cleaner).

When I run the application I get the following error (directly after trying to run/debug): (translated from Dutch so might not be 100% literally equal):

There has not been found a matching constructor in type PcgTools.Resources.Strings. You can use the instruction Arguments or FactoryMethod, to create this type.

There is a constructor in file Strings.Designer.cs:

namespace PcgTools.Resources {
...
public class Strings {
...

[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute
   ("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Strings() {
    }

However, it is generated so I cannot even change it.

Btw, without changing the code has worked (about a week ago), but then about 30% of the time when debugging it gave this error and after trying again this exception did not occur.

回答1:

Does your PcgTools.Resources.Strings class have a public default constructor? I think it's complaining that it can't create the object because it can't find a matching constructor and since you're not using Arguments, it's looking for a default constructor (one with no arguments). The constructor needs to be public, not internal or private.

Since the code is generated, you'll need to find some way around this. Using the FactoryMethods thing might work. To do that, set up another class like

namespace PcgTools.Resources
{
    public static class StringResourceHelper
    {
        public static strings GetStringResources()
        {
            return new Resources.Strings();
        }
    }
}

then in your XAML you can do:

<res:Strings x:FactoryMethod="res:StringResourceHelper.GetStringResources" 
             x:Key="LocStrings"/>


回答2:

See also:

http://dotnet.dzone.com/news/did-you-know-silverlight-class

In short: do not name the namespaces .Resources It should not be named Resources but something else otherwise you will get the error as described above.

Edit: However, it seems after changing resource strings, the overwritten file (..Designer.cs) still contains the internal instead of public constructor resulting in the error from the question.