Page 1 of 2
Dynamic Xaml Instantiation
Posted: 25 Mar 2013, 22:23
by EisenbergEffect
Consider the following Xaml:
<Border>
<ContentControl x:Name="Placeholder" />
</Border>
A common scenario is that based on program logic, I need to instantiate different UIs and add set them as the Placeholder's Content. Is there a way to do this? I'm primarily working in Unity and didn't see an existing API. I thought that I might be able to use the UIRenderer class to perform the instantiation and then use the GetRoot API to pull out the control tree and set it on the ContentControl. I haven't tried this yet, but wanted to hear from you on a recommendation and/or any drawbacks to this.
Re: Dynamic Xaml Instantiation
Posted: 25 Mar 2013, 22:59
by sfernandez
Loading dynamically a XAML is a trivial task using C++ API. You just use the Resource System to load the XAML resource, and get the contents of the resource to assign them to the appropriate container:
#include <NsCore/NsSystem.h>
#include <NsResource/IResourceSystem.h>
#include <NsGui/IUIResource.h>
#include <NsGui/ContentControl.h>
using namespace Noesis;
using namespace Noesis::Resource;
using namespace Noesis::Gui;
void LoadXAML(ContentControl* container, const NsChar* xamlFile)
{
const Ptr<IResourceSystem>& resourceSystem = NsGetSystem<IResourceSystem>();
Ptr<IUIResource> xamlResource = NsDynamicCast<Ptr<IUIResource> >(resourceSystem->Load(xamlFile));
container->SetContent(xamlResource->GetRoot());
}
The API that is currently available in Unity that deals with XAML files is a bit more complex (it creates and associates a GUI Renderer to the loaded content), but in our next beta release it will be possible to do exactly what you want to do

Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 10:51
by bwheatley
Has this beta been released to allow this with Unity yet?
Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 11:07
by sfernandez
Sure, you can load XAML files in runtime by calling NoesisGUISystem.LoadXAML():
Assets/UI_XAML/TestOther.xaml
<Grid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button x:Name="btn" Width="200" Height="100"/>
</Grid>
public class Test : MonoBehaviour
{
void Start()
{
Noesis.Grid grid = NoesisGUISystem.LoadXAML<Noesis.Grid>("Assets/UI_XAML/TestOther.xaml");
var gui = GetComponent<NoesisGUIPanel>();
var root = gui.GetRoot<Noesis.Grid>();
var container = roo.FindName<Noesis.ContentControl>("container");
container.SetContent(grid);
}
}
Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 11:15
by bwheatley
Oh cool thanks for the quick response. I've been loving Noesis and slowly converting everything from NGUI over. I'm just trying to figure out the best way to dynamically instantiate new elements in a xaml (like multiple image boxes).
But maybe there is a dynamic combo box i could potentially use instead of trying to manually instantiate new xaml elements.
Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 11:43
by sfernandez
If you are creating data at runtime that you want to be displayed in the UI, you better try to use Data Binding:
viewtopic.php?f=3&t=75#p2388.
You create in Unity the classes that represent your Data. Then you can create your interface in Blend (or any editor you like) to design how to represent your data (using Bindings to the properties provided by the Data classes). Finally, when application is started, you set in the interface root the DataContext (the ViewModel that exposes the properties), and that's all.
Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 11:44
by sfernandez
Another sample of Data Binding:
viewtopic.php?f=12&t=391
Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 19:16
by bwheatley
Thank you for the thoughtful and helpful answers! I'll check them out now.
Money well spent especially with getting help.

Re: Dynamic Xaml Instantiation
Posted: 16 Aug 2014, 19:32
by bwheatley
Thanks for pointing me in the right direction. Looks like I need to use databinding plus a <scrollviewer> to allow for horizental scrolling of inventory items.
Right now i worked off your databinding tutorial and i got it working with a dropdown.
I appreciate the help!
https://www.evernote.com/shard/s36/sh/7 ... 0985491f4c
Re: Dynamic Xaml Instantiation
Posted: 18 Aug 2014, 23:13
by wwizz
I have a follow-up question on this topic. I managed to dynamic load an xaml this way, however getting references of elements in the loaded xaml by name fails.
To clarify see the next files:
The container xaml
<UserControl
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:noesis="clr-namespace:NoesisGUIExtensions" >
<Border x:Name="container" />
</UserControl>
The loaded xaml
<UserControl
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:noesis="clr-namespace:NoesisGUIExtensions"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="300">
<Grid>
<Border BorderThickness="2" Padding="10" >
<Grid x:Name="mainGrid">
<StackPanel x:Name="buttonPanel">
<TextBlock>Title</TextBlock>
<Button x:Name="Button1" Content="Button1" />
<Button x:Name="Button2" Content="Button2" />
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>
Then I use the following code to load a xaml
public void Start()
{
var loaded = NoesisGUISystem.LoadXaml<UserControl>("Assets/PressIt.GUI/Test1.xaml");
gui = FindObjectOfType<NoesisGUIPanel>();
var root = gui.GetRoot<FrameworkElement>();
var container = root.FindName<Border>("container");
container.SetChild(loaded);
container.SetVisibility(Visibility.Visible);
button1= container.FindName<Button>("Button1");
button2 = container.FindName<Button>("Button2");
button1.Click += OnButton1Click; //<=== NULL reference exception
button2.Click += OnButton2Click;
}
The button1 and button2 variables are null, meaning that the FindName<Button>("...") failed. Note that the xaml works perfectly if I load the xaml statically in NoesisGUIPanel.
Any ideas?