1

Given a class that implements IValueConverter:

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ...;
    }

    // Never called.
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ...;
    }
}

It is straightforward to create a keyed ResourceDictionary entry, if that is not a nested class:

<ContentView
    ...
    xmlns:converters="clr-namespace:MyNamespace.Converters" 
    x:Class "MyNamespace.MyView">
    
    <ContentView.Resources>
        <ResourceDictionary>
            <converters:MyConverter x:Key="myConverter" />
            ...

But suppose it is a nested class:

public class OuterClass
{
    public class MyConverter : IValueConverter
    ...

A nested class can't be referred to as an element name (would not be valid XML nor XAML):

// Won't compile.
<ContentView.Resources>
    <ResourceDictionary>
        <converters:OuterClass.MyConverter x:Key="myConverter" />
        ...

OR

        <converters:OuterClass+MyConverter x:Key="myConverter" />
        ...

HOWEVER, if there is an equivalent XAML that moves the class name to a property value, then it can be done, as described in my answer here:

<??? SomeProperty="converters:OuterClass+MyConverter" x:Key="myConverter" />

OR MAYBE ONE OF THESE, per x:Type Markup Extension:

<x:Type TypeName="converters:OuterClass+MyConverter" x:Key="myConverter" />
<x:Type TypeName="converters:OuterClass.MyConverter" x:Key="myConverter" />
<??? SomeProperty="{x:Type converters:OuterClass+MyConverter}" x:Key="myConverter" />

I've tried all of these, plus other variations (e.g. replace ??? with IValueConverter, or object).
So far I've always gotten either build-time problem:

Type '...' is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter.

OR at runtime when open the view:

System.RuntimeType doesn't implement interface Xamarin.Forms.IValueConverter
... SIGABRT

Q: Is there a way to specify an IValueConverter resource, when the type is a nested class?

NOTE:

  • I've verified that the class works if it is not nested. [That is the solution I am using now. But I would prefer to nest the classes within the code behind class, because this is only used on this view.]
ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
  • Would you mind sharing us a baisc, minimal project to test ? You can upload it to github and attach the link here . – Wen xu Li Apr 04 '22 at 09:40
  • @WenxuLi-MSFT - take any sample that includes an `IValueConverter`. For example, [Value Converters doc](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/converters) links to source code; browse to [IntToBoolConverter](https://github.com/xamarin/xamarin-forms-samples/blob/main/DataBindingDemos/DataBindingDemos/DataBindingDemos/Converters/IntToBoolConverter.cs). Change `public class IntToBoolConverter : IValueConverter { ... }` to `public class OuterClass { public class IntToBoolConverter : IValueConverter { ... } }`. Try to use it from XAML. – ToolmakerSteve Apr 04 '22 at 15:23
  • If you just want to keep it together for logical reasons you can create a flat outer class inside the class. – Wen xu Li Apr 11 '22 at 09:06
  • How do you refer to it? If my class is named `MyView`, and I put inside it `public class MyConverter : IValueConverter`, then I haven't found any way to refer to `MyConverter` from `MyView.xaml`. If do ``, get error `"MyConverter was not found"`. Using an `xmlns:myNamespace=...` declaration line doesn't help, because that only makes it possible to refer to classes directly in that namespace. `` only works if MyConverter is directly in the namespace, not inside `MyView`. I haven't found any way in a xaml element name to refer to `MyView.MyConverter` class. – ToolmakerSteve Apr 11 '22 at 23:32
  • ... Therefore, I am forced to to do `namespace MyNameSpace { class MyConverter { ... } }`, even though I'd rather not have `MyConverter` visible to any class except `MyView`. Its a minor point; I am just curious whether there is any way to make a xaml element or resourcedictionary entry of type `namespace MyNameSpace { class MyView { class MyConverter ... } } }`. So far, I haven't found any. – ToolmakerSteve Apr 11 '22 at 23:37

0 Answers0