Page 1 of 1

Sample noesis test with simple button

Posted: 22 Mar 2020, 16:31
by stevensen
Hi,
I'm a beginner in noesis. I'm trying to run this c#-code and unity3d below. It's a sample from the noesis dokumentation.
It throws this error:

InvalidCastException: Specified cast is not valid.
test.Start () (at Assets/Test01/test.cs:12)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Noesis;

public class test : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
       Noesis.Grid root = (Noesis.Grid) Noesis.GUI.LoadXaml("Assets/Test01/test.xaml");  // <<< throws error
        Button button = (Button)root.FindName("button");
        button.Click += (object sender, RoutedEventArgs args) =>
        {
            System.Console.WriteLine("Button was clicked");
        };

    }

    // Update is called once per frame
    void Update()
    {
    
    }
}
I added Noesis to use Noesis.Grid.
Whats wrong with this cast? Hope anybody can help me.

Re: Sample noesis test with simple button

Posted: 23 Mar 2020, 11:00
by tkaczz
Hi,
I'm a beginner in noesis. I'm trying to run this c#-code and unity3d below. It's a sample from the noesis dokumentation.
It throws this error:

InvalidCastException: Specified cast is not valid.
test.Start () (at Assets/Test01/test.cs:12)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Noesis;

public class test : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
       Noesis.Grid root = (Noesis.Grid) Noesis.GUI.LoadXaml("Assets/Test01/test.xaml");  // <<< throws error
        Button button = (Button)root.FindName("button");
        button.Click += (object sender, RoutedEventArgs args) =>
        {
            System.Console.WriteLine("Button was clicked");
        };

    }

    // Update is called once per frame
    void Update()
    {
    
    }
}
I added Noesis to use Noesis.Grid.
Whats wrong with this cast? Hope anybody can help me.
I would rather use this approach:
- create xaml, with/without code-behind
- attach noesis view component to GameObject, pick previously created xaml
- manipulate controls/set DataContext from script

Example from my old project (WARNING bad coding practices)
public class StatsHUD_Presenter : MonoBehaviour {
    private PlayerPawn playerPawn;
    private Inventory playerInventory;

    private FrameworkElement root;
    private ProgressBar healthBar;

    private TextBlock currentWeight;
    private TextBlock maxWeight;

    [Inject]
    public void Construct(
        PlayerPawn playerPawn,
        Inventory playerInventory
    ) {
        this.playerPawn = playerPawn;
        this.playerInventory = playerInventory;
    }

    private void Start() {
        root = GetComponent<NoesisView>().Content;
        healthBar = (ProgressBar)root.FindName("HealthBar");

        currentWeight = (TextBlock)root.FindName("CurrentWeight");
        maxWeight = (TextBlock)root.FindName("MaxWeight");

        InitSubscribes();
        InitWeight();
    }

    private void InitSubscribes() {
        SetProgressBarSubscribes(playerPawn.Health, healthBar);
    }

    private void InitWeight() {
        currentWeight.Text = playerInventory.Weight.Current.Value.ToString();
        maxWeight.Text = playerInventory.Weight.Max.Value.ToString();

        playerInventory.Weight.Current
            .Subscribe(newWeight => {
                currentWeight.Text = newWeight.ToString();
            })
            .AddTo(this);

        playerInventory.Weight.Max
            .Subscribe(newMaxWeight => {
                maxWeight.Text = newMaxWeight.ToString();
            })
            .AddTo(this);
    }

    private void SetProgressBarSubscribes(NumericalStat numStat, ProgressBar progBar) {
        numStat.Min
            .Subscribe(newMin => {
                progBar.Minimum = newMin;
            })
            .AddTo(this);

        numStat.Current
            .Subscribe(newCurrent => {
                progBar.Value = newCurrent;
            })
            .AddTo(this);

        numStat.Max
            .Subscribe(newMax => {
                progBar.Maximum = newMax;
            })
            .AddTo(this);
    }
}
<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    mc:Ignorable="d">
    <Viewbox
        Width="100"
        Height="75"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch">
        <Grid Width="100" Height="75">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.Background>
                <SolidColorBrush Opacity="0.5" Color="Black" />
            </Grid.Background>
            <ProgressBar
                Name="HealthBar"
                Grid.Row="0"
                Margin="5"
                Foreground="Red"
                Value="50" />
            <StackPanel
                Name="CarryWeight"
                Grid.Row="4"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Orientation="Horizontal">
                <TextBlock Foreground="White" Text="Weight : " />
                <TextBlock
                    Name="CurrentWeight"
                    Foreground="White"
                    Text="12.5" />
                <TextBlock Foreground="White" Text="/" />
                <TextBlock
                    Name="MaxWeight"
                    Foreground="White"
                    Text="25.5" />
            </StackPanel>
        </Grid>
    </Viewbox>
</Page>

Re: Sample noesis test with simple button

Posted: 25 Mar 2020, 11:32
by sfernandez
It's a sample from the noesis dokumentation
I guess you extracted that code from the Events tutorial, right?
We should probably add another code block for Unity like this to avoid confusion:
NoesisView view = GetComponent<NoesisView>();
Button button = (Button)view.Content.FindName("button");
button.Click += (object sender, RoutedEventArgs args) =>
{
    UnityEngine.Debug.Log("Button was clicked");
};
In Unity we process xaml files to create assets. You can drag generated asset for your "test.xaml" file to the "Main camera" gameobject. That will automatically attach a NoesisView component to the gameobject with the dragged xaml asset assigned. If you create a MonoBehavior with my previous code and attach it to the Main Camera gameobject, the rendered button will print to Unity console the message every time is clicked.

Please let me know if that works for you.

Re: Sample noesis test with simple button

Posted: 25 Mar 2020, 16:24
by stevensen
Thanks for the answers.

It works!! I used parts from tkaczz sample, this was very helpful. thanks a lot to you. @tkaczz

Of course I'm still trying the 2nd code, but only tonight.
But thanks for that too. #by sfernandez

Re: Sample noesis test with simple button

Posted: 31 Mar 2020, 15:58
by jsantos
You welcome. Thanks for your feedback. Marking this as solved.