1 year ago

#368125

test-img

ToolmakerSteve

In a XAML ResourceDictionary, how create a reference to an IValueConverter that is a nested class?

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.]

xaml

xamarin.forms

inner-classes

resourcedictionary

0 Answers

Your Answer

Accepted video resources