Currently I'm playing around with WPF data binding and I came to an issue I dont understand. So I post the problem here, maybe you have and idea whats geoing wrong.
At first: I'm working with Visual Studio 2008 under Windows Vista 32bit, the problem is also present in Windows 7 RC1 64bit, latest updates/service packs are installed except Vista, its still running with SP1.
Here is the problem:
I'm not able to set a ValueConverter in an inherited Binding class.
Here is my custom binding class:
public class MyBinding : Binding
{
public MyBinding() : base() { }
public MyBinding(string path) : base(path) { }
}
This class should do exactly the same as the original Binding class because currently it does not implement any own logic. I can use this class in XAML as follows:
<TextBlock Text="{local:MyBinding SomeProperty}" />
local is the namespace where the MyBinding class is implemented.
Now here comes the first thing I dont understand. VS2008 shows the following error message in its error window (the original message is in german, because I'm running a german system - i dont have the english error message, so I will try to translate)
Kein Konstruktor des MyBinding-Typs weist 1-Parameter auf.
(No constructor of type MyBinding takes 1 argument)
Althoug this error is display the project compiles just fine and the MyBinding class is working as expected. Why Visual Studio does not find the corresponding constructor (wich, I would say, is properly implemented)?
I can prevent these message if I change the XAML code to this:
<TextBlock Text="{local:MyBinding Path=SomeProperty}" />
The error message is gone because the MyBinding's default constructor is called, everything works fine, ok...
Now I would like to set a ValueConverter to my property binding, XAML looks like this:
<Window.Resources>
<local:MyValueConverter x:Key="converter" />
</Window.Resources>
[...]
<TextBlock Text="{local:MyBinding Path=SomeProperty, Converter={StaticResource converter}}" />
[...]
..., and here I get the following error while compiling (original in german and I think, I've also found the original message in english):
Beim Analysieren einer Markup Extension wurde für den Typ "MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension" die unbekannte Eigenschaft "Converter" gefunden. Zeile X Position Y.
(Unknown property 'Converter' for type 'MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension' encountered while parsing a Markup Extension. Line x position Y)
Now I cannot compile anymore because VS does not find the converter property (wich is a public property of the original Binding class).
I've managed to get the MyBinding class to run with a converter I specify, but only with a little hack:
I've added the following property to the MyBinding class:
public Type ConverterType
{
get { return Converter == null ? null : Converter.GetType(); }
set { Converter = value == null ? null : (IValueConverter)Activator.CreateInstance(value); }
}
... and XAML changes to this:
<TextBlock Text="{local:MyBinding Path=SomeString, ConverterType=local:MyValueConverter}" />
Now my project compiles and runs fine. Actually I think, its a nice solution, because you dont have to specify the converter as a static resource and the binding expression looks a little bit more clearly to me. But at the end, this cannot be the solution.
So can anyone tell me what I've done wrong? Why I cannot set the Converter property in my custom Binding class?
Thank you!
Best regards,
René
after some further testing with markup extensions, this issue passed my way over and over again and after some more googling, I think I've found a confirmation, that this is a bug in Visual Studio designer. Everyone, whos interested in that should take a look at
http://www.hardcodet.net/2008/04/nested-markup-extension-bug
Best regards,
René
Inheriting from Binding probably isn't the best solution. If you simply want to get around declaring a converter as a static resource, try creating a Singleton of your converter, and use it like so:
Text="{Binding Path=Foo, Converter={x:Static local:MyConverter.Converter}}"
Alternately, you could try a markup extension as shown here.
Thank you for your response!
In general I have no problem with the binding expression syntax and declaring the converter before using it. What I've written above is just a nice result of the workaround for my major problem. I want to create my own Binding class and pass my own converter to it the same way I would do it with the original Binding class.
I just want to understand the error message, wich is presented to me by VS. I think it must have a reason, either I'm doing something wrong or there is a bug in Visual Studio/WPF.
Until this afternoon I was pretty sure that the problem is sitting in front of the computer. But I've posted this question in two other user groups (also at MSDN in the forum for WPF). Till now you are the only person who respond. And so I came to the idea, that it also might be a problem with visual studio... I dont know.
Again, thank you very much, I will have a closer look on the page you've posted (currently just a short one).
Have a nice weekend!
Best regards,
René
I had the same problem, do not know why, but I put the custom binding on another dll and it worked.
Related
I've been writing a Xamaring Bindings Library for a third party Android JAR and become stumped at how to convert an int field in a class to an enum.
I've created a C# enum for the int fields using EnumFields.xml and have also got this successfully return out of methods using EnumMethods.xml but in one place a class is instead returned which exposes an int field which should be my enum.
I've tried:
<method jni-name="error" parameter="return" clr-enum-type=....
Within EnumMethods but couldnt get it to work, i then tried
<attr path=".......[#name='Result']/field[#name='error']"
name="managedType">
Within Metadata.xml but also couldn't get it to map. I can change its property name but not its return type.
Within the JavaDoc it says the following:
public final int error
And in my generated C# I get:
// Metadata.xml XPath field reference: path="/api/package[#name='cn.com.aratek.util']/class[#name='Result']/field[#name='error']"
Have I missed something obvious?
A year later I ended up stumbling across my own post after hitting the same issue again.
For reference my error was trying to use managedType as the name. You simply use type.
e.g within metadata.xml
<attr path=".......[#name='Result']/field[#name='error']" name="type">NewEnumName</attr>
References I used to help figure this out:
https://gist.github.com/JonDouglas/dda6d8ace7d071b0e8cb - great
resource with lots of examples
The updated Microsoft documentation
https://learn.microsoft.com/en-us/xamarin/android/platform/binding-java-library/customizing-bindings/java-bindings-metadata
Finally, simply looking at other peoples source on git hub. the
GTK# bindings particularly
https://github.com/mono/gtk-sharp/blob/master/gtk/Gtk.metadata
Am I doing something wrong or is this the same bug that was reported in 2008?
In the XAML snippet below I am using a custom markup extension:
<Image Source="{wpfx:IconEx Fill={StaticResource mybrush},
Icon={StaticResource myicongeometry}}" />
wpfx is a prefix for my CLR Namespace that I imported in XAML.
IconEx is my custom public Markup Extension class that derives from MarkupExtension.
The image element is rendered correctly in the designer (that is the markup extension does its job), however when I try to build it in either VS 2015 or VS 2017 RC, I get this:
Error: Unknown property 'Fill' for type 'MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension' encountered while parsing a Markup Extension.
Note that the property Fill is public on my markup extension class, as is the class itself. If I change the values of both Fill and Icon properties to not use { } nested markup extension syntax, everything works. The problem is though that I cannot do that.
So, given that it's almost 2017 now, are there any workarounds that do not use the nested property syntax, as it looks like an overkill? Or did I do something wrong, and it;'s not a bug? Maybe I miss some attributes on my markup extension class or it's properties.
What is a modern approach to use localization in UWP?
JsonLocalization plugin for UWP did not pull neither Json nor ResourseLoader plugins. Moreover, it did not install any bootstrap files (not sure if they still needed in UWP).
Based on assumption that it works correctly without bootstraping and that plugin already contains all necessary stuff, i implemented sample like it was instructed in video and got "||ViewHeader" string instead of localized one. And json content is obviously something like
{
"ViewHeader":"Test view header"
}
I added breakpoint to NativeLanguageConverter.Convert and figured out that value.TextProvider.ResourceLoader is null. I have added all those plugins manually, but error is the same - seems they are unregsitered, so i have to bootstrap them.
What should i do in this case?
UPDATE: Indeed, the problem is about missing bootstraps: https://github.com/MvvmCross/MvvmCross-Plugins/issues/113
However, even after adding them, i'm still getting string in format "|%AssemblyName%|%ViewmodelName%|%KeyName%" instead of "%ValueName%". In debugger, i can see that dictionary contains proper key-value pair, but it somehow returns not value, but a formatted key.
After spending several hours, i had figured out the working combination.
In order to fix the issue, i have to create a different LanguageBinders for different ViewModels.
public IMvxLanguageBinder FirstViewModelTextSource
{
get
{
return new MvxLanguageBinder(GeneralConstants.LocalizationGeneralNamespace, "FirstViewModel");
}
}
And then on the view:
<TextBlock Text="{Binding FirstViewModelTextSource,Converter={StaticResource Language},ConverterParameter=ViewHeader,FallbackValue=ViewHeader,Mode=OneTime}"
Margin="10,0,10,50" TextWrapping="Wrap"/>
I have a Working and Compileable WPF-Solution in a which I needed to copy to another directory.
Now I experience the following Problem, which I nowhere found similar on the web:
In some Projects every UserControl I created, isnt compileable anymore. Somehow Terms like DataContext or InitializeComponent() "do not exist in the current context".
Usually this is a case of wrong namespaces, or classnaming between the xaml and xaml.cs. As my code is all compileable in the original repo, this can not be the case. I've also checked that build action is set to Page, which is also a common issue in this case.
As I've found out, even newly created UserControls have the same problems. So I compared the projectfiles from the source and targed destination, which seemed to have no difference at all.
At this point I'll ask the community. Have you ever experienced a similar problem? What do you think i could check, too?
Thanks alot.
In my case there's been a reference inside my project which was wrong but that wasn't reported.
I solved my problem with readding all my references even if they were meant as correct.
Check the x:Class property on the pasted UserControl and make sure it matches the fully qualified class name of the codebehind
for instance in you have the following in MyUserControl.xaml.cs:
...
namespace MyApp
{
public partial class MyUserControl: UserControl
{
public MyUserControl()
{
InitializeComponent();
}
}
}
Then make sure the you have x:Class="MyApp.MyUserControl in your MyUserControl.xaml file
I have a XAML UserControl, which uses a converter contained in the same project.
xmlns:filter="clr-namespace:SampleModuleFilter" - namespace definition
So far so good. However, when I move the converter into another assembly and adjust the namespaces and references accordingly, I get the following exception:
XamlParseException - "Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception. The inner exception states "The method or operation is not implemented." which is just weird.
The namespace after the move into another library looks like this:
xmlns:filter="clr-namespace:SampleLibrary.Converters;assembly=SampleLibrary"
The converter resource definition is:
<filter:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
and I use it like so:
Visibility="{Binding DisplayLabel, Converter={StaticResource ResourceKey=boolToVisibilityConverter}}"
IntelliSense can obviously see the library, since it works ok (offers the converter class after I write the namespace prefix).
Any ideas what the problem might be?
You have to reference your assembly also in the code-behind file.
If you reference the assembly only in the XAML part, the compiler returns a "failed to load xxx.dll" exception.
You have also to make a direct call to the connected assembly making something like this:
var dummy = new MyExternalAssemby.MyType();
or just this in a new line of code
new MyExternalAssemby.MyType();
without putting the result in a dummy variable.
Usually I do that in a static constructor.
I think this is a bug in the XAML interpreter because the XAML is not compiled but just "translated" in the BAML (binary XAML). So, if you reference a type in XAML without creating an "hard" reference in the code behind the NET linker ignores it at all.
HTH
Lorenzo
Instead of just:
xmlns:filter="clr-namespace:SampleModuleFilter"
Reference the assembly too
xmlns:filter="clr-namespace:SampleModuleFilter;assembly=SampleModuleFilterAssemblyName"
That should do the trick.
That is strange; we have our converters all located in a central library, and it works fine. Assuming references and namespaces are correct, the only thing I could suggest would be to clean and rebuild the two projects in question.
Is "SampleLibrary.dll" used somewhere in your code ?
I got a strange bug where referenced assemblies only used in xaml file are skipped at compile time, and do not appear in the dll dependencies.