realesmedia
Topic Author
Posts: 85
Joined: 18 May 2016, 10:26

[C++] Register multiple events for collection

05 Jan 2017, 12:01

How to register one event to each element of collection if last one changes dynamicaly?
How to register event on each addition and removing of elements?

Model, XAML:
<Grid.Resources>
	<DataModel x:Name="dataModel" />
	<DataTemplate x:Key="ListTemplate">
		<CheckBox x:Name="CheckListBoxItem" Content="{Binding content}" Tag="{Binding value}"/>
	</DataTemplate>
</Grid.Resources>
View, XAML:
<ListBox x:Name="CheckListBox" ItemsSource="{Binding TheList}"  DataContext="{StaticResource dataModel}" ItemTemplate="{StaticResource ListTemplate}"/>
Use case, for example:
1. user click the button;
2. new checkbox appending to listbox as item;
3. checkbox have registered event OnCheck();

Second use case:
1. user select listbox element which is checkbox;
2. user click the button;
3. listbox have the element removed and no event connected to it;
Last edited by realesmedia on 09 Jan 2017, 11:52, edited 1 time in total.
 
User avatar
ai_enabled
Posts: 221
Joined: 18 Jul 2013, 05:28
Contact:

Re: [C++] Register multiple events for collection

05 Jan 2017, 12:33

Hi!

AFAIK, it's not possible with the item templates. But you can bind the IsChecked property of the checkbox:
<CheckBox Content="{Binding content}" Tag="{Binding value}" IsChecked="{Binding IsCheckedPropertyInItemDataContext}" />
This way you don't need to use XAML events. Also it works for buttons in the same way - instead of subscribing to the click event you can simply bind the button Command property.

BTW, we're making our second big game with NoesisGUI, we have over hundred of controls and don't using any XAML events (and rarely use any events in codebehind). Only databinding. MVVM pattern is super useful and very easy to learn. We expect our modding community to learn it with our tutorials (not yet done) and modify/extend our game UI. It's even easier as we have UI live reloading feature (so it will rebuild UI and code nearly instantly).

Regards!
AtomicTorch Studio Pte. Ltd. http://atomictorch.com
 
realesmedia
Topic Author
Posts: 85
Joined: 18 May 2016, 10:26

Re: [C++] Register multiple events for collection

05 Jan 2017, 13:22

But you can bind the IsChecked property of the checkbox
Can you give C++ code example?
 
User avatar
ai_enabled
Posts: 221
Joined: 18 Jul 2013, 05:28
Contact:

Re: [C++] Register multiple events for collection

05 Jan 2017, 13:36

I'm using C# SDK so I cannot write a quick example in C++...
But you can check v1.3 Doc/Gui.Core.CommandsTutorial.html - there is a good tutorial how to create a view model with the command properties (for buttons).
It works in the same way to checkboxes, but you don't need commands - you need to create a simple Boolean field in the view model and bind to it.
Then you need to simply make an observable collection of these view models. Perhaps you already done this as I see you have binding of ItemsSource="{Binding TheList}" and binding of Content and Tag properties of the checkbox in the item template - so you need to add to this view model class a new Boolean property and bind it in XAML as I showed above. In this Boolean property set method (which will be invoked by NoesisGUI automatically when you click on the checkbox) you can do any logic you wanted to do in the checkbox click event handler.

Regards!
AtomicTorch Studio Pte. Ltd. http://atomictorch.com
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: [C++] Register multiple events for collection

06 Jan 2017, 13:24

But you can bind the IsChecked property of the checkbox
Can you give C++ code example?
As ai_enabled suggested you can bind to the IsChecked property, and execute any code when set to true:
<Grid.Resources>
   <DataModel x:Name="dataModel" />
   <DataTemplate x:Key="ListTemplate">
      <CheckBox x:Name="CheckListBoxItem" Content="{Binding content}" Tag="{Binding value}"
          IsChecked="{Binding checked}"/>
   </DataTemplate>
</Grid.Resources>
So you have to expose a boolean property named 'checked' in your item view model:
class ItemVM: public Noesis::BaseComponent
{
public:
  // ...

  bool GetChecked() const { return _checked; }
  void SetChecked(bool checked)
  {
    if (_checked != checked)
    {
      _checked = checked;
      if (_checked)
      {
        // do whatever you want here...
      }
    }
  }

private:
  bool _checked;

  NS_IMPLEMENT_INLINE_REFLECTION(ItemVM, Noesis::BaseComponent)
  {
    NsProp("checked", &ItemVM::GetChecked, &ItemVM::SetChecked);
  }
};
 
realesmedia
Topic Author
Posts: 85
Joined: 18 May 2016, 10:26

Re: [C++] Register multiple events for collection

09 Jan 2017, 10:06

Thanks for replies.
When I put IsCheck event into data template it doesn't work (get/set functions doesn't call). Without data template works great.
<Grid.Resources>
	<DataModel x:Name="dataModel" />
	<DataTemplate x:Key="ListTemplate">
		<CheckBox x:Name="CheckListBoxItem" Content="{Binding content}" Tag="{Binding value}" IsChecked="{Binding OnChecked}"/>
	</DataTemplate>
</Grid.Resources>
<StackPanel VerticalAlignment="Center" Width="auto">
	<ListBox x:Name="CheckListBox" ItemsSource="{Binding TheList}"  DataContext="{StaticResource dataModel}" ItemTemplate="{StaticResource ListTemplate}"/>
</StackPanel>
public:
void SetOnChecked(bool);
bool GetOnChecked() const { 
	return mChecked;
}
private:
NS_IMPLEMENT_INLINE_REFLECTION(DataModel, BaseComponent) {
	NsProp("OnChecked", &DataModel::GetOnChecked, &DataModel::SetOnChecked);
}
bool mChecked;
 
User avatar
ai_enabled
Posts: 221
Joined: 18 Jul 2013, 05:28
Contact:

Re: [C++] Register multiple events for collection

09 Jan 2017, 10:12

@realesmedia, it seems you've put this C++ code into the view model containing the list ("TheList") property - it will not work. You need to put it into the the view model class used for items of this list (the view model containing the "content" and "value" properties). Your data template binds to the list elements view models.
AtomicTorch Studio Pte. Ltd. http://atomictorch.com
 
realesmedia
Topic Author
Posts: 85
Joined: 18 May 2016, 10:26

Re: [C++] Register multiple events for collection

09 Jan 2017, 10:17

@realesmedia, it seems you've put this C++ code into the view model containing the list ("TheList") property - it will not work. You need to put it into the the view model class used for items of this list (the view model containing the "content" and "value" properties). Your data template binds to the list elements view models.
I'll try to separate logic. Will report on try.
 
realesmedia
Topic Author
Posts: 85
Joined: 18 May 2016, 10:26

Re: [C++] Register multiple events for collection

09 Jan 2017, 10:54

You are right. Separated logic for view model works.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: [C++] Register multiple events for collection

09 Jan 2017, 20:19

Yes, the "onChecked" property should be added to the view model of the item itself, not the view model that exposes the list of items. Maybe it was not clear enough in my code snippet, sorry for the confusion.

It works fine now then? could we mark this as solved?

Who is online

Users browsing this forum: Google [Bot], jsantos and 1 guest