User avatar
blafollette
Topic Author
Posts: 7
Joined: 15 Jul 2020, 11:54

Native type is not registered error when calling FindName("myName") as ResourceDictionary

14 Aug 2020, 15:19

I've got a big collection of flags that are stored in a <ResourceDictionary x:Name="myName"> in xaml. I wrote an IValueConverter that takes an input string from an item property in a collection and returns the svg resource. The code behind for the xaml exposes a ResouceDictionary property that I use in the IValueConverter to reference the dictionary and return values by key.

This is all working great in WPF, but in Unity when I call FindName("myName") to manually assign the ResourceDictionary to the accessor property, it throws an exception "System.InvalidOperationException: Native type is not registered". What am I doing wrong? Am I missing something?

Or, more generally, is there a better approach to displaying svg flags or icons or whatever than storing them as keyed resources in xaml?

Help! :)

for reference, here's some of my code:
The wrapper xaml
<UserControl x:Class="MyNamespace.FlagsWrapper"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyNamespace"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">

    <UserControl.Resources>
		<ResourceDictionary x:Name="FlagsResource"> Source="Styles/FlagsCollection.xaml"/>
    </UserControl.Resources>
</UserControl>
The code-behind
public partial class FlagsWrapper : UserControl
    {
        public ResourceDictionary FlagsDictionary { get; set; }

        public FlagsWrapper()
        {
            InitializeComponent();

#if !NOESIS
            FlagsDictionary = FlagsResource;
#endif
        }

#if NOESIS
        private void InitializeComponent()
        {
            Noesis.GUI.LoadComponent(this, "Assets/WPF/FlagsWrapper.xaml");
            FlagsDictionary = FindName("FlagsResource") as ResourceDictionary;
        }
#endif
    }
And finally my accessor in the IValueConverter:
        private ResourceDictionary m_flags;
        public ResourceDictionary Flags
        {
            get
            {
                if (m_flags == null)
                    m_flags = new FlagsWrapper().FlagsDictionary;

                return m_flags;
            }
        }
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

14 Aug 2020, 20:27

It seems there is a bug when defining a ResourceDictionary with x:Name inside <Resources> node, could you please report it in our bugtracker?

Anyway, assigning the dictionary to the converter like this looks too complex for me, shouldn't be enough to expose a Flags property in the converter and set it in the xaml directly:
public class FlagConverter : Noesis.IValueConverter
{
  public ResourceDictionary Flags { get; set; }

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { ... }
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { ... }
}
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:Testing">
  <Grid.Resources>
    <local:FlagConverter x:Key="flagConverter">
      <local:FlagConverter.Flags>
        <ResourceDictionary Source="FlagsCollection.xaml"/>
      </local:FlagConverter.Flags>
    </local:FlagConverter>
  </Grid.Resources>
  ...
</Grid>
Or, more generally, is there a better approach to displaying svg flags or icons or whatever than storing them as keyed resources in xaml?
Using keyed resources/templates to store svg icons is fine, this way you can reuse them and share other resources like brushes to reduce memory usage.
 
User avatar
blafollette
Topic Author
Posts: 7
Joined: 15 Jul 2020, 11:54

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

15 Aug 2020, 14:39

Thanks so much! I will certainly go ahead and make a report.

As for the solution you suggest, I actually did exactly this as my initial approach! However, it broke the VS designer view, and part of my whole reason for taking this approach was to allow for design-time display of these SVGs. :) Apparently, the Design viewer uses a different object to instantiate the ResourceDictionary than the runtime, and it didn't want to play nice. And having the designer view being broken and refusing to render was not an option.

My next approach was to simply create a code-behind which derived from ResourceDictionary for the xaml file where I define the <ResourceDictionary> for the SVGs as the top-level element. I then simply instanced a new version of this file in my converter's accessor for the dictionary on demand. This actually worked, too! (in both WPF and Unity/Noesis) However, defining the code behind class for the <ResourceDictionary> was spamming the Unity console with errors complaining that I couldn't define a ResourceDictionary inside of a ResourceDictionary (?), I would have to recreate the scenario to get the exact error message, but I decided I wasn't satisfied with this approach since it broke the pattern used with the other style xamls that I have anyway.

So hence, finally, my third approach, which got us here! :D

Thanks again!
 
User avatar
blafollette
Topic Author
Posts: 7
Joined: 15 Jul 2020, 11:54

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

17 Aug 2020, 13:21

For any curious, the workaround that has everything working was to implement my Resources node in my Flags Wrapper xaml as follows:
    <UserControl.Resources>
        <ResourceDictionary x:Name="FlagsResource">
            <ResourceDictionary.MergedDictionaries >
                <ResourceDictionary Source="Styles/FlagsCollection.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <local:ISOtoFlagConverter x:Key="flagConverter" x:Name="FlagConverter">
                <local:ISOtoFlagConverter.Flags>
                    <ResourceDictionary Source="Styles/FlagsCollection.xaml"/>
                </local:ISOtoFlagConverter.Flags>
            </local:ISOtoFlagConverter>
        </ResourceDictionary>
    </UserControl.Resources>
And then to use compilation directives in the code behind as follows:
    public partial class FlagsWrapper : UserControl
    {
        public ResourceDictionary FlagsDictionary { get; set; }

        public FlagsWrapper()
        {
            InitializeComponent();

#if !NOESIS
            FlagsDictionary = FlagsResource;
#endif
        }

#if NOESIS
        private void InitializeComponent()
        {
            Noesis.GUI.LoadComponent(this, "Assets/FlagsWrapper.xaml");
            var converter = FindName("FlagConverter") as FlagConverter;
            FlagsDictionary = converter.Flags;
        }
#endif
    }
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

20 Aug 2020, 10:59

As for the solution you suggest, I actually did exactly this as my initial approach! However, it broke the VS designer view, and part of my whole reason for taking this approach was to allow for design-time display of these SVGs. :) Apparently, the Design viewer uses a different object to instantiate the ResourceDictionary than the runtime, and it didn't want to play nice. And having the designer view being broken and refusing to render was not an option.
The solution I proposed works fine with Blend designer, please find attached a sample project for you to test. I guess you implemented a slightly different approach.
Attachments
FlagsTest.zip
(10.24 KiB) Downloaded 73 times
 
User avatar
blafollette
Topic Author
Posts: 7
Joined: 15 Jul 2020, 11:54

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

20 Aug 2020, 11:04

It's entirely possible the error was all my own doing! :) Thanks for the sample, I'll give it a test as soon as I have the opportunity!

Thanks very much, again, for all your help!
 
User avatar
blafollette
Topic Author
Posts: 7
Joined: 15 Jul 2020, 11:54

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

20 Aug 2020, 15:30

Yup, this totally works just as you said! I don't know what I got wrong before, but I'm no longer even able to reproduce the original design view error I got. So, no idea where I went wrong before! :)

Thanks again!
 
User avatar
jsantos
Site Admin
Posts: 3905
Joined: 20 Jan 2012, 17:18
Contact:

Re: Native type is not registered error when calling FindName("myName") as ResourceDictionary

24 Aug 2020, 13:32

Great! Marking as solved

Who is online

Users browsing this forum: No registered users and 56 guests