- EisenbergEffect
- Posts: 19
- Joined:
Dynamic Xaml Instantiation
Consider the following Xaml:
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.
Code: Select all
<Border>
<ContentControl x:Name="Placeholder" />
</Border>
-
sfernandez
Site Admin
- Posts: 3183
- Joined:
Re: Dynamic Xaml Instantiation
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:
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
Code: Select all
#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());
}
Re: Dynamic Xaml Instantiation
Has this beta been released to allow this with Unity yet?
-
sfernandez
Site Admin
- Posts: 3183
- Joined:
Re: Dynamic Xaml Instantiation
Sure, you can load XAML files in runtime by calling NoesisGUISystem.LoadXAML():
Assets/UI_XAML/TestOther.xaml
Assets/UI_XAML/TestOther.xaml
Code: Select all
<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>
Code: Select all
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
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.
But maybe there is a dynamic combo box i could potentially use instead of trying to manually instantiate new xaml elements.
-
sfernandez
Site Admin
- Posts: 3183
- Joined:
Re: Dynamic Xaml Instantiation
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.
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.
-
sfernandez
Site Admin
- Posts: 3183
- Joined:
Re: Dynamic Xaml Instantiation
Another sample of Data Binding: viewtopic.php?f=12&t=391
Re: Dynamic Xaml Instantiation
Thank you for the thoughtful and helpful answers! I'll check them out now.
Money well spent especially with getting help.
Money well spent especially with getting help.
Re: Dynamic Xaml Instantiation
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
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
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
The loaded xaml
Then I use the following code to load a xaml
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?
To clarify see the next files:
The container xaml
Code: Select all
<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>
Code: Select all
<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
Code: Select all
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;
}
Any ideas?
Who is online
Users browsing this forum: No registered users and 5 guests