Can't find file with UserControl but not (in t

2019-08-08 09:14发布

问题:

I have a UserControl in a the DLL Controls, a converter in the DLL Base and language resources in the DLL Languages.

When I combine everything the following way, everything works fine:

<Label Content="{Binding FallbackValue='[Design] Name', ConverterParameter='Name', Converter={StaticResource Translate}}"
           ContentStringFormat="{}{0}:"/>

No errors and when I run my application the correct word for the parameter Name is loaded (in my case Naam for Dutch).

I also try this on my WatermarkTextBox like this:

<c:WatermarkTextBox Watermark="{Binding FallbackValue='[Design] Name *', ConverterParameter='Name', Converter={StaticResource Translate}}" />

But then I get the following error:

Could not load file or assembly 'file:///C:...\Languages.dll' or one of its dependencies. The system cannot find the file specified.

Why does this happen with my WatermarkTextBox in Controls DLL and not with the Label?

回答1:

The first step here is to make sure, that the assembly file Languages.dll is actually present in the application directory (usually, bin/Debug/). If it isn't - as the error message says - the system cannot find the file specified... The solution in this case is to reference the assembly Languages.dll in your application project. To avoid this, make sure that every time you add a reference to an assembly, you also add references to this assembly's dependencies. I.e. if you have an application project App which references a library LibA.dll and LibA references a library LibB.dll, you should add a reference to LibB.dll in your App project as well. That way, all required assemblies will always be copied to the output directory.

If the assembly is correctly located in the output directory, but you still get the error message, in 99% of the cases the problem is a mismatch in the building targets, alas the platform for which the assemblies were built. Make sure all projects target the same platform (x86, for example). You can check the target in the projects Properties tabs.

EDIT:

Ok, I just now understood you're talking about the design time error in Visual Studio's XAML Designer :) The issue is the name of the assembly: Noru.Languages.dll. I suppose, the ending .Languages is considered a resource name and Visual Studio prohibits resource names in assembly names. There's a registry entry HKLM\Software\Microsoft\VisualStudio\12.0\Designers\AllowResourcesInFilename, maybe experimenting with that can resolve the issue. Not 100% sure, though. Anyway, if you rename the assembly to Nori.Language.dll in the project's properties and rebuild everything, design time support is back and the controls show up correctly in the designer.

EDIT 2:

Really strange behavior altogether... Well, this line in the Class Language might very well be the cause? Try specifying the full string here... Does this work?

ResourceManager rm = new ResourceManager("Noru.Languages.Language", System.Reflection.Assembly.LoadFrom("Noru.Languages.dll"));

EDIT 3:

Obviously, the problem was the line I mentioned above in Edit 2. I've experimented a bit:

/// <summary>
/// Will return the requested text in the language the application is in. Case sensitive.
/// </summary>
/// <param name="s">Provide a listed String from the language files.</param>
/// <returns>Will return a System.String in the language of the application.</returns>
public static string GetText(string s)
{
    //return Culture.ToString();
    //return Assembly.GetExecutingAssembly().FullName;
    //ResourceManager rm = new ResourceManager("Noru.Lang.Resource1", Assembly.GetAssembly(typeof(Language)));
    //ResourceSet rs = rm.GetResourceSet(Culture, true, true);

    var rs = LanguageResource.ResourceManager;
    try
    {
        return rs.GetString(s);
    }
    catch (Exception)
    {
        return "not found";
    }
}

The last version (not commented out) works, because I've generated code for the resource files by setting AccessModifier to public in the resource editor (double click on the resource file, you'll find it in the toolbar).

This version (never mind about the resource name, I tried different versions here):

ResourceManager rm = new ResourceManager("Noru.Lang.Resource1", Assembly.GetAssembly(typeof(Language)));

threw another error, saying it cannot find the resource inside the assembly. I think there was something wrong about the usage of ResourceManager here. I'm not an expert here, so I can't tell why. I just know that the last version seems to work as expected... I hope, you'll find the same ;)