Page 1 of 1

ViewModel "not set to an instance of an object"

Posted: 16 Jan 2014, 21:56
by mtanfield
I'm currently working on creating a test case using databinding and a viewmodel that can be viewed in Unity, but at the same time allow the .xaml to be edited in Blend/Visual Studio/etc. and show up in the design view.

The issue I am having is that Visual Studio/Blend outputs an error, "Object reference not set to an instance of an object.", for the creation of the TestUIViewModel resource:
<local:TestUIViewModel x:Key="viewModel"/>
I think the issue is that the files are in separate directories and cannot find the references, but I'm not sure. I have a .csproj, TestUI.csproj, created in a separate directory (Documents/NoesisTest/TestUI/) with Blend, and I have the .xaml file and .cs files linked to that project.

TestUI.xaml (located in Documents/NoesisTest/Assets/Test UI Assets/):
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestUI"
             Height="300" Width="300">
    <Grid>
        <Grid.Resources>
            <local:TestUIViewModel x:Key="viewModel"/>
        </Grid.Resources>
        <Grid.DataContext>
            <Binding Source="{StaticResource viewModel}"/>
        </Grid.DataContext>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Click Me!" FontSize="32" Command="{Binding ClickMeCommand}"/>
        <TextBox Grid.Row="1" Text="{Binding SampleText, Source={StaticResource viewModel}}"/>
    </Grid>
</UserControl>
TestUIViewModel.cs (located in Documents/NoesisTest/Assets/Plugins/TestUI/:
using UnityEngine;
using System;

namespace TestUI
{
    [Noesis.Extended]
    public class TestUIViewModel : Noesis.SerializableComponent
    {
        string _sampleText = string.Empty;
        public string SampleText
        {
            get
            {
                return _sampleText;
            }
            set
            {
                if (_sampleText != value)
                {
                    _sampleText = value;
                    NotifyPropertyChanged("SampleText");
                }
            }
        }

        public Noesis.DelegateCommand ClickMeCommand
        {
            get;
            private set;
        }

        public TestUIViewModel()
        {
            ClickMeCommand = new Noesis.DelegateCommand(OnClickMe);
        }

        private void OnClickMe()
        {
            SampleText = "Hello!!";
        }
    }
}
Any ideas?

Re: ViewModel "not set to an instance of an object"

Posted: 17 Jan 2014, 11:31
by sfernandez
Hi,

First of all, you have to modify the xaml file a bit because of a bug about nested markup extensions that will be solved for the next version. Try this one:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestUI"
             Height="300" Width="300">
    <Grid>
        <Grid.Resources>
            <local:TestUIViewModel x:Key="viewModel"/>
        </Grid.Resources>
        <Grid.DataContext>
            <StaticResource ResourceKey="viewModel"/>
        </Grid.DataContext>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Content="Click Me!" FontSize="32" Command="{Binding ClickMeCommand}"/>
        <TextBox Grid.Row="1" Text="{Binding SampleText}"/>
    </Grid>
</UserControl>
Then I created a Blend project, and added a new Class item (TestUIViewModel.cs) with the following code:
using System;

namespace TestUI
{
    public class TestUIViewModel
    {
        public TestUIViewModel()
        {
        }
    }
}
Finally I linked (in the 'Projects' tab in Blend editor right click the project name, and select 'Link to existing item...' in the context menu, see Blend tutorial for more info) the TestUI.xaml from the Unity Assets/ directory.

This setup is working for me to view and edit the xaml file in Blend editor.
Let me know if it works also for you.

Re: ViewModel "not set to an instance of an object"

Posted: 17 Jan 2014, 15:38
by mtanfield
I still get the "not set to an instancde of an object" message, but it seems to work in Blend. Now I just have an error message in Unity:

The type or namespace name `DelegateCommand' does not exist in the namespace `Noesis'. Are you missing an assembly reference?

Re: ViewModel "not set to an instance of an object"

Posted: 17 Jan 2014, 15:53
by jsantos
DelegateCommand is not part of noesisGUI (it happens the same with WPF). You can implement it easily, as shown in the Commands tutorial.
[Noesis.Extended]
public class DelegateCommand : Noesis.BaseCommand
{
    private readonly System.Action _action;

    public DelegateCommand(System.Action action)
    {
        _action = action;
    }

    public bool CanExecuteCommand(Noesis.BaseComponent parameter)
    {
        return true;
    }

    public void ExecuteCommand(Noesis.BaseComponent parameter)
    {
        _action();
    }
}

Re: ViewModel "not set to an instance of an object"

Posted: 17 Jan 2014, 16:03
by mtanfield
Ok, it works now! :D

One other thing I noticed was that if I made the DelegateCommand class part of the TestUI namespace, a warning conflict would show up between the actual file and the class data in the ScriptAssembly .dll. By removing the namespace designation, everything works as it should!

Thanks again!

Re: ViewModel "not set to an instance of an object"

Posted: 17 Jan 2014, 18:44
by sfernandez
DelegateCommand is defined in one of our samples (Commands sample). If you didn't delete the NoesisGUI/Samples/ directory, that class will conflict with the one you defined in TestUI namespace when using DelegateCommand without fully qualifying its name.

Re: ViewModel "not set to an instance of an object"

Posted: 17 Jan 2014, 20:38
by jsantos
This is something we have to improve by the way:

viewtopic.php?f=3&t=269