Skip to content

Instantly share code, notes, and snippets.

@jaredthirsk
Last active June 14, 2021 18:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredthirsk/38d797960b2df41e4718 to your computer and use it in GitHub Desktop.
Save jaredthirsk/38d797960b2df41e4718 to your computer and use it in GitHub Desktop.
Wire up a C# code-behind file to a NoesisGUI XAML file automatically, by convention and reflection
//#define TRACE_XamlCodeBehind
#define WARN_XamlCodeBehind
// Installation Recommendation: Place this file as a loose C# file in your Unity Assets tree.
// Copyright: placed in Public Domain by Jared Thirsk, 2015
// Note: Noesis plans to add code-behind support. Once they do this, this file should become obsolete.
// Created for NoesisGUI 1.2.3
using Noesis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
public class XamlCodeBehind : MonoBehaviour
{
public string CodeBehindClass;
private FrameworkElement content;
private object codebehindObject;
NoesisGUIPanel noesisGUI;
void Start()
{
#region NoesisGUI
noesisGUI = GetComponent<NoesisGUIPanel>();
if (noesisGUI == null)
{
UnityEngine.Debug.LogWarning("[XamlCodeBehind] No NoesisGUIPanel attached to this object. Nothing for a XamlCodeBehind class to bind to.");
return;
}
var subpath = noesisGUI._xamlFile;
var filename = System.IO.Path.GetFileNameWithoutExtension(subpath);
#if TRACE_XamlCodeBehind
UnityEngine.Debug.Log("XamlFile: " + filename);
#endif
if (String.IsNullOrEmpty(CodeBehindClass))
{
#if trueX
string defaultNamespacePrefix = "LionFire.Gaxastar.Views.";
CodeBehindClass = defaultNamespacePrefix + filename;
#else
CodeBehindClass = filename;
#endif
}
#endregion
content = noesisGUI.GetContent();
if(content==null)
{
UnityEngine.Debug.LogError("Failed to get NoesisGUI content for " + noesisGUI._xamlFile);
return;
}
#if TRACE_XamlCodeBehind
else{
UnityEngine.Debug.Log("Got NoesisGUI content: " + (content == null ? "null" : content.GetType().FullName));
}
#endif
try
{
Type codebehindType = Type.GetType(CodeBehindClass);
if (content == null)
{
UnityEngine.Debug.LogError("Failed to get codebehind type for " + noesisGUI._xamlFile);
return;
}
#if TRACE_XamlCodeBehind
else{
UnityEngine.Debug.Log("[XamlCodeBehind] Got code behind Type: " + (codebehindType == null ? "" : codebehindType.FullName));
}
#endif
codebehindObject = Activator.CreateInstance(codebehindType, new object[] { content });
foreach (var methodInfo in codebehindType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
if (!methodInfo.Name.Contains('_')) continue;
if (methodInfo.Name == "obj_address") continue;
var chunks = methodInfo.Name.Split('_');
if (chunks.Length != 2) continue;
if (chunks[0] == "get" || chunks[0] == "set") continue;
if (chunks[0] == "add" || chunks[0] == "remove") continue;
object target = content.FindName(chunks[0]);
if (target == null)
{
#if WARN_XamlCodeBehind
UnityEngine.Debug.LogWarning("[CODEBEHIND] Did not find element: " + chunks[0] + " for method: " + methodInfo.Name);
#endif
continue;
}
#if TRACE_XamlCodeBehind
else
{
UnityEngine.Debug.Log("[codebehind] Found element: " + chunks[0]);
}
#endif
var eventInfo = target.GetType().GetEvent(chunks[1], BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
if (eventInfo == null)
{
#if WARN_XamlCodeBehind
UnityEngine.Debug.LogWarning("[CODEBEHIND] Did not find event: " + chunks[1] + " for method: " + methodInfo.Name + " on type " + target.GetType().FullName);
#endif
continue;
}
#if TRACE_XamlCodeBehind
else
{
UnityEngine.Debug.Log("[codebehind] Found event: " + chunks[1]);
}
#endif
Delegate del = Delegate.CreateDelegate(eventInfo.EventHandlerType, codebehindObject, methodInfo);
try
{
eventInfo.AddEventHandler(target, del);
}
catch (Exception ex)
{
UnityEngine.Debug.LogError("[CODEBEHIND] Failed to attach event for method: " + methodInfo.Name + ". Event type: " + eventInfo.EventHandlerType.FullName + ", Delegate type: " + del.GetType().FullName + ", Delegate return type: " + methodInfo.ReturnType + " with parameter types: " + methodInfo.GetParameters().Select(p => p.ParameterType.FullName).Aggregate((x, y) => x + ", " + y) + " Exception: " + ex);
}
}
}
catch (Exception ex)
{
UnityEngine.Debug.LogError("[CODEBEHIND] " + ex);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment