UE4
Topic Author
Posts: 62
Joined: 29 Dec 2017, 06:32

How to use UserControl in another xaml?

06 Feb 2018, 09:16

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.
 
User avatar
hcpizzi
Site Admin
Posts: 236
Joined: 09 Feb 2012, 12:40

Re: How to use UserControl in another xaml?

06 Feb 2018, 11:28

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.
 
UE4
Topic Author
Posts: 62
Joined: 29 Dec 2017, 06:32

Re: How to use UserControl in another xaml?

06 Feb 2018, 13:10

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().
 
User avatar
hcpizzi
Site Admin
Posts: 236
Joined: 09 Feb 2012, 12:40

Re: How to use UserControl in another xaml?

06 Feb 2018, 14:20

Glad I could help :)
 
aberro
Posts: 3
Joined: 03 Feb 2018, 20:33

Re: How to use UserControl in another xaml?

07 Feb 2018, 20:18

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); 
}
 
User avatar
hcpizzi
Site Admin
Posts: 236
Joined: 09 Feb 2012, 12:40

Re: How to use UserControl in another xaml?

07 Feb 2018, 21:35

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.
 
aberro
Posts: 3
Joined: 03 Feb 2018, 20:33

Re: How to use UserControl in another xaml?

08 Feb 2018, 01:28

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.
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to use UserControl in another xaml?

08 Feb 2018, 11:04

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?
 
aberro
Posts: 3
Joined: 03 Feb 2018, 20:33

Re: How to use UserControl in another xaml?

10 Feb 2018, 20:10

May I ask what do you find unexpected here?
Only that sometimes I can use local path and sometimes I can't.
 
User avatar
jsantos
Site Admin
Posts: 2904
Joined: 20 Jan 2012, 17:18
Contact:

Re: How to use UserControl in another xaml?

15 Feb 2018, 10:01

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.

Who is online

Users browsing this forum: No registered users and 1 guest