Page 1 of 1
How to use UserControl in another xaml?
Posted: 06 Feb 2018, 09:16
by UE4
I defined a UserControl(MyControl) in a.Xaml, then I created a MainWindow.Xaml, and in MainWindow.Xaml I add <local:MyControl/> and <Button/>, all it looks well while running in WPF, but no MyControl in UE4, some advices?
I create a MyControl class, an ElementExtensions class, and call NsRegisterComponent in StartupModule as TutorialSamples does in my project.
Re: How to use UserControl in another xaml?
Posted: 06 Feb 2018, 11:28
by hcpizzi
Hi,
We're in the process of porting the Menu3D sample to UE4. I'll post in the forum when that happens. For now, here's the code behind class for one of the custom controls that sample uses:
class MainMenu : public Noesis::UserControl
{
public:
MainMenu()
{
Initialized() += Noesis::MakeDelegate(this, &MainMenu::OnInitialized);
InitializeComponent();
}
virtual ~MainMenu() {}
void FadeIn()
{
if (FadeInStoryboard)
{
FadeInStoryboard->Begin();
}
}
void FadeOut()
{
if (FadeOutStoryboard)
{
FadeOutStoryboard->Begin();
}
}
private:
void InitializeComponent()
{
UNoesisXaml* Xaml = LoadObject<UNoesisXaml>(nullptr, TEXT("/Game/Assets/NoesisGUI/Samples/Menu/MainMenu"));
Xaml->LoadComponent(this);
}
void OnInitialized(Noesis::BaseComponent* Sender, const Noesis::EventArgs& Args)
{
Noesis::Ptr<Noesis::ResourceKeyString> FadeInKey = Noesis::ResourceKeyString::Create("FadeIn");
FadeInStoryboard.Reset(FindResource<Noesis::Storyboard>(FadeInKey.GetPtr()));
Noesis::Ptr<Noesis::ResourceKeyString> FadeOutKey = Noesis::ResourceKeyString::Create("FadeOut");
FadeOutStoryboard.Reset(FindResource<Noesis::Storyboard>(FadeOutKey.GetPtr()));
if (FadeInStoryboard)
{
FadeInStoryboard->Completed() += MakeDelegate(this, &MainMenu::OnFadeInCompleted);
}
Start.Reset(FindName<Noesis::ToggleButton>("Start"));
Settings.Reset(FindName<Noesis::ToggleButton>("Settings"));
Exit.Reset(FindName<Noesis::ToggleButton>("Exit"));
PreviewKeyDown() += MakeDelegate(this, &MainMenu::ProcessKeyDown);
}
void OnFadeInCompleted(Noesis::BaseComponent* Sender, const Noesis::TimelineEventArgs& Args)
{
if (Start)
{
Start->Focus();
}
}
void ProcessKeyDown(Noesis::BaseComponent* Sender, const Noesis::KeyEventArgs& Args)
{
if (Args.key == Noesis::Key_Return)
{
if (Start->GetIsKeyboardFocused())
{
Start->GetCommand()->Execute(nullptr);
}
else if (Settings->GetIsKeyboardFocused())
{
Settings->GetCommand()->Execute(nullptr);
}
else if (Exit->GetIsKeyboardFocused())
{
Exit->GetCommand()->Execute(nullptr);
}
}
else if (Args.key == Noesis::Key_Escape)
{
Exit->GetCommand()->Execute(nullptr);
}
}
Noesis::Ptr<Noesis::Storyboard> FadeInStoryboard;
Noesis::Ptr<Noesis::Storyboard> FadeOutStoryboard;
Noesis::Ptr<Noesis::ToggleButton> Start;
Noesis::Ptr<Noesis::ToggleButton> Settings;
Noesis::Ptr<Noesis::ToggleButton> Exit;
NS_IMPLEMENT_INLINE_REFLECTION(MainMenu, Noesis::UserControl)
{
NsMeta<Noesis::TypeId>("Menu3D.MainMenu");
}
};
The bit that's different from the native code samples is in InitializeComponent, where it does the LoadObject to load the imported NoesisXaml asset, and then uses NoesisXaml::LoadComponent to initialize the user control.
Please, let us know if you still can't manage to get it working. If it doesn't, please check your output log for any messages in the LogNoesis channel.
Re: How to use UserControl in another xaml?
Posted: 06 Feb 2018, 13:10
by UE4
Hi,
We're in the process of porting the Menu3D sample to UE4. I'll post in the forum when that happens. For now, here's the code behind class for one of the custom controls that sample uses:
class MainMenu : public Noesis::UserControl
{
public:
MainMenu()
{
Initialized() += Noesis::MakeDelegate(this, &MainMenu::OnInitialized);
InitializeComponent();
}
virtual ~MainMenu() {}
void FadeIn()
{
if (FadeInStoryboard)
{
FadeInStoryboard->Begin();
}
}
void FadeOut()
{
if (FadeOutStoryboard)
{
FadeOutStoryboard->Begin();
}
}
private:
void InitializeComponent()
{
UNoesisXaml* Xaml = LoadObject<UNoesisXaml>(nullptr, TEXT("/Game/Assets/NoesisGUI/Samples/Menu/MainMenu"));
Xaml->LoadComponent(this);
}
void OnInitialized(Noesis::BaseComponent* Sender, const Noesis::EventArgs& Args)
{
Noesis::Ptr<Noesis::ResourceKeyString> FadeInKey = Noesis::ResourceKeyString::Create("FadeIn");
FadeInStoryboard.Reset(FindResource<Noesis::Storyboard>(FadeInKey.GetPtr()));
Noesis::Ptr<Noesis::ResourceKeyString> FadeOutKey = Noesis::ResourceKeyString::Create("FadeOut");
FadeOutStoryboard.Reset(FindResource<Noesis::Storyboard>(FadeOutKey.GetPtr()));
if (FadeInStoryboard)
{
FadeInStoryboard->Completed() += MakeDelegate(this, &MainMenu::OnFadeInCompleted);
}
Start.Reset(FindName<Noesis::ToggleButton>("Start"));
Settings.Reset(FindName<Noesis::ToggleButton>("Settings"));
Exit.Reset(FindName<Noesis::ToggleButton>("Exit"));
PreviewKeyDown() += MakeDelegate(this, &MainMenu::ProcessKeyDown);
}
void OnFadeInCompleted(Noesis::BaseComponent* Sender, const Noesis::TimelineEventArgs& Args)
{
if (Start)
{
Start->Focus();
}
}
void ProcessKeyDown(Noesis::BaseComponent* Sender, const Noesis::KeyEventArgs& Args)
{
if (Args.key == Noesis::Key_Return)
{
if (Start->GetIsKeyboardFocused())
{
Start->GetCommand()->Execute(nullptr);
}
else if (Settings->GetIsKeyboardFocused())
{
Settings->GetCommand()->Execute(nullptr);
}
else if (Exit->GetIsKeyboardFocused())
{
Exit->GetCommand()->Execute(nullptr);
}
}
else if (Args.key == Noesis::Key_Escape)
{
Exit->GetCommand()->Execute(nullptr);
}
}
Noesis::Ptr<Noesis::Storyboard> FadeInStoryboard;
Noesis::Ptr<Noesis::Storyboard> FadeOutStoryboard;
Noesis::Ptr<Noesis::ToggleButton> Start;
Noesis::Ptr<Noesis::ToggleButton> Settings;
Noesis::Ptr<Noesis::ToggleButton> Exit;
NS_IMPLEMENT_INLINE_REFLECTION(MainMenu, Noesis::UserControl)
{
NsMeta<Noesis::TypeId>("Menu3D.MainMenu");
}
};
The bit that's different from the native code samples is in InitializeComponent, where it does the LoadObject to load the imported NoesisXaml asset, and then uses NoesisXaml::LoadComponent to initialize the user control.
Please, let us know if you still can't manage to get it working. If it doesn't, please check your output log for any messages in the LogNoesis channel.
Thanks, all woks well , after change GUI::LoadComponent to UE4's LoadObject().
Re: How to use UserControl in another xaml?
Posted: 06 Feb 2018, 14:20
by hcpizzi
Glad I could help

Re: How to use UserControl in another xaml?
Posted: 07 Feb 2018, 20:18
by aberro
Can you please give example for C# too?
I've tries this, but can't get it work:
private void InitializeComponent()
{
GUI.LoadComponent(this, "EditorWindow.xaml");
var xaml = (NoesisXaml)GUI.LoadXaml("PartsPanel.xaml");
xaml.LoadComponent(this);
}
Re: How to use UserControl in another xaml?
Posted: 07 Feb 2018, 21:35
by hcpizzi
Hi,
Our Menu3D Unity sample has user controls. Here's the link to the sample:
https://github.com/Noesis/Tutorials/tre ... nu3D/Unity
Here's a link to one of the code-behind classes for one of the controls:
https://github.com/Noesis/Tutorials/blo ... nu.xaml.cs
As you can see there, all you need is the first LoadComponent call, and remember to call InitializeComponent from your constructor.
Re: How to use UserControl in another xaml?
Posted: 08 Feb 2018, 01:28
by aberro
Well, looks like I've only needed full path to xaml file. That's unexpected, because when I've used control directly (without custom controls), it builds and works.
Re: How to use UserControl in another xaml?
Posted: 08 Feb 2018, 11:04
by jsantos
Well, when you use
UserControls in a XAML, we need a way to find the corresponding XAML file. Being Unity in this case, you need to provide a path compatible with Unity.
private void InitializeComponent()
{
Noesis.GUI.LoadComponent(this, "Assets/NoesisGUI/Samples/Menu3D/MainWindow.xaml");
}
May I ask what do you find unexpected here?
Re: How to use UserControl in another xaml?
Posted: 10 Feb 2018, 20:10
by aberro
May I ask what do you find unexpected here?
Only that sometimes I can use local path and sometimes I can't.
Re: How to use UserControl in another xaml?
Posted: 15 Feb 2018, 10:01
by jsantos
You can use relatives path within a XAML, but when using paths from code, you always need to provide global paths, there is no way we can know what the path would be relative to.