Gwynneth
Topic Author
Posts: 15
Joined: 20 Apr 2017, 18:31

Editable resource dictionaries

24 May 2018, 12:35

Hey, I'm working on a system which lets users create their own color schemes to be used by the UI. However, apparently editing a ResourceDictionary is not yet implemented in Noesis: the Add and Remove methods as well as iterating the ResourceDictionary (ICollection, IDictionary and IEnumerable) are currently missing. Would it be possible to add this functionality or is there some other way in which ResourceDictionaries can be edited?

Secondly, part of the color scheme system needs to load XAML files. Currently I've created two ways in which to load XAML files (and then turn them into ResourceDictionaries).

The first method loads the NoesisXAML assets created by NoesisGUI:
NoesisXaml redScheme = (NoesisXaml)Resources.Load("ColorSchemes/Red", typeof(NoesisXaml));
The second method loads in a text file. Currently, I'm loading a text file from Unity's Resources folder for testing but the same method should work for files on disk:

NoesisXaml redScheme = ScriptableObject.CreateInstance<NoesisXaml>();
redScheme.content = Encoding.ASCII.GetBytes(Resources.Load<TextAsset>("ColorSchemes/Red").text);
redScheme.source = "Assets/Resources/ColorSchemes/Red";

I would expect both of these NoesisXaml instances to be the same, but they aren't. The differences are small and both NoesisXaml's produce seemingly working ResourceDictionaries. However, is there a reason why they are different and perhaps not work in certain situations? The differences are:
  • Most importantly: the content property differs: the NoesisXaml asset contains three more bytes: 239 187 191.
  • When loading a NoesisXaml asset the NoesisXaml is already _registered whereas manually loading only sets _registered to true after .Load() has been called.
  • The properties fonts, texturePaths, textures and xamls are initialized when loading a NoesisXaml asset (most likely does not matter).
Lastly, although optional, I'd like to save a custom ResourceDictionary to a xaml file. Saving the NoesisXaml.content property to a file works. However, since the goal is to edit the ResourceDictionary the NoesisXaml instance will not contain the changes made by the user. Therefore, is there a way to convert the ResourceDictionary to a valid XAML string?

Kind regards,
Gwynn
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: Editable resource dictionaries

05 Jun 2018, 21:10

I see that ResourceDictionary C# interface does not include the IDictionary methods, that's something we have to fix.
Could you please create a ticket in our bugtracker and we will include them in a following release.

Without that the only way to add/remove items right now in the dictionary is by using the RegisterName/UnregisterName methods.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

Re: Editable resource dictionaries

05 Jun 2018, 21:18

Lastly, although optional, I'd like to save a custom ResourceDictionary to a xaml file. Saving the NoesisXaml.content property to a file works. However, since the goal is to edit the ResourceDictionary the NoesisXaml instance will not contain the changes made by the user. Therefore, is there a way to convert the ResourceDictionary to a valid XAML string?
There is no way now in Noesis to output a UI element or dictionary to disk. WPF offers a XamlWriter to achieve that:
https://stackoverflow.com/questions/104 ... ry-to-disk

Could you add it to our bugtracker?, if there are some requests about this feature we can think of implementing it.
 
User avatar
jsantos
Site Admin
Posts: 3906
Joined: 20 Jan 2012, 17:18
Contact:

Re: Editable resource dictionaries

05 Jun 2018, 22:12

Most importantly: the content property differs: the NoesisXaml asset contains three more bytes: 239 187 191.
I don't know if this could be related to UTF8 encoding. Are these extra bytes appearing at the end? This is the way we are loading the content (you have the code in NoesisPostprocessor.cs) from FileStream:
xaml.content = new byte[file.Length];
file.Read(xaml.content, 0, (int)file.Length);
When loading a NoesisXaml asset the NoesisXaml is already _registered whereas manually loading only sets _registered to true after .Load() has been called.
Yes, you can ignore this difference. It makes sense, because you have to invoke .Load() soon or later.
The properties fonts, texturePaths, textures and xamls are initialized when loading a NoesisXaml asset (most likely does not matter).
Yes, in case you fill the content manually you are also in charge of setting the dependencies.

Apart from that, the two paths are exactly the same and should produce the same runtime objects.

Who is online

Users browsing this forum: camimamedov, Semrush [Bot] and 44 guests