Re: [Unity] Binding to an object other than BaseComponent
Posted: 24 Jul 2014, 07:57
In uFrame Element designer we create a TestChat element, add the Input and Output properties and the SayHelloCommand. We also connect a TestChatView to the element. This will create TestChatViewModel.cs, TestChatController.cs and TestChatView.cs.I have no idea what you are talking about here, can you elaborate?In the meantime I know I can write Views to bind ViewModel properties to XAML controls, but it's redundant and error-prone. Would be a much more elegant solution if you could just plug in the ViewModel.

Now we can create the following XAML (derived from the sample Command.xaml). This is what I meant by plugging in the ViewModel.
Code: Select all
<Grid
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" mc:Ignorable="d"
xmlns:local="clr-namespace:TestChat">
<Grid.Resources>
<local:TestChatViewModel x:Key="TestChatViewModel"/>
</Grid.Resources>
<Viewbox>
<StackPanel DataContext="{StaticResource TestChatViewModel}">
<TextBox Text="{Binding Input, Mode=TwoWay}"/>
<Button Content="Say Hello" Command="{Binding SayHelloCommand}" />
<TextBlock Text="{Binding Output}" />
</StackPanel>
</Viewbox>
</Grid>Since that is currently not the case, we have to bind the controls to the ViewModel properties ourselves. We also need to rip-out the bindings from the XAML and add Names to the controls instead so we can find them. The TestChatView.cs would look like this:
Code: Select all
using UnityEngine;
using Noesis;
public partial class TestChatView
{
private NoesisGUIPanel _noesisGUIPanel;
private Grid _grid;
private TextBox _inputTextbox;
private Button _SayHelloButton;
private TextBlock _OutputTextblock;
public override void Awake()
{
base.Awake();
_noesisGUIPanel = GetComponent<NoesisGUIPanel>();
_grid = _noesisGUIPanel.GetRoot<Grid>();
_inputTextbox = _grid.FindName<TextBox>("textbox_Input");
_SayHelloButton = _grid.FindName<Button>("button_SayHelloCommand");
_OutputTextblock = _grid.FindName<TextBlock>("textblock_Output");
_SayHelloButton.Click += _SayHelloButton_Click;
}
private void _SayHelloButton_Click(BaseComponent sender, RoutedEventArgs e)
{
ExecuteSayHelloCommand();
}
public override void InputChanged(string value)
{
base.InputChanged(value);
_inputTextbox.SetText(value);
}
public override void OutputChanged(string value)
{
base.OutputChanged(value);
if (string.IsNullOrEmpty(value))
{
_OutputTextblock.SetText(string.Empty);
}
else
{
_OutputTextblock.SetText(value);
}
}
public void Update()
{
TestChat.Input = _inputTextbox.GetText();
}
}Code: Select all
<Grid
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" mc:Ignorable="d">
<Viewbox>
<StackPanel>
<TextBox Name="textbox_Input"/>
<Button Content="Say Hello" Name="button_SayHelloCommand" />
<TextBlock Name="textblock_Output" />
</StackPanel>
</Viewbox>
</Grid>Finally you have to add TestChatView.cs to the Unity scene which would otherwise not be necessary.


So I have talked about this with uFrame's developer who told me the main problem is that Mono does not contain System.Windows.Input.ICommand nor System.Collections.Specialized.ObservableCollection. Remember that Noesis GUI also doesn't use System.Windows.Input.ICommand, but Noesis.BaseCommand instead. I wonder if there's a solution that solves this kind of solution for both Noesis and uFrame.
Here's a similar case about Implementing MVVM in WPF without using System.Windows.Input.ICommand.