Page 1 of 1

Iteraction.Trigger inside DataTemplate

Posted: 22 Sep 2021, 16:57
by Logrus
Hi
        <DataTemplate DataType="{x:Type SubHierarchy}">
            <TreeView ItemContainerStyle="{StaticResource Style.SceneMultiSelectedTreeViewItem}" ItemsSource="{Binding Root.Childs}">

                <i:Interaction.Behaviors>
                    <TreeViewMultipleSelectionBehavior x:Name="msb" SelectedItems="{Binding SelectedNodes, Mode=TwoWay}" />
                </i:Interaction.Behaviors>

                <i:Interaction.Triggers>
                    <EventTrigger EventName="MultiSelectionChanged" SourceName="msb">
                        <InvokeCommandAction Command="{Binding ChangeSelectedNodesCommand}" />
                    </EventTrigger>
                </i:Interaction.Triggers>

            </TreeView>
        </DataTemplate>
EventTrigger fires if set on the TreeView event.

If bind to TreeViewMultipleSelectionBehavior, then it is not called.

In debug, Trigger binds to event (EventTriggerBase.cpp)
 Noesis::EventHandler& handler = *(Noesis::EventHandler*)event->GetContent(source);
 handler += MakeDelegate(this, &EventTriggerBase::OnDelegateEvent); ///Call 
when called MultiSelectionChanged,
Delegate.Size () is empty

Re: Iteraction.Trigger inside DataTemplate

Posted: 23 Sep 2021, 09:37
by Logrus
The problem is in Behavior. Handler Binding occurs after
CloneCommonCore(const Freezable* source)
, therefore Handler bind only to source (Behavior) in DataTemplate.

This is how it works, not sure if this is correct
	void TreeViewMultipleSelectionBehavior::CloneCommonCore(const Freezable* source)
	{
		Base::CloneCommonCore(source);
		
		auto behavior = (TreeViewMultipleSelectionBehavior*)source;
		mMultiSelectionChanged = behavior->mMultiSelectionChanged;

		//Store pointer  
		mSourceBehavior = behavior;
	}
	void TreeViewMultipleSelectionBehavior::OnTreeViewItemMouseUp(BaseComponent* sender, const MouseButtonEventArgs& e)
	{
			if (mSourceBehavior) {
				mMultiSelectionChanged = mSourceBehavior->mMultiSelectionChanged;
			}
			mMultiSelectionChanged(this, MultiSelectionChangedEventArgs{ this, MultiSelectionChangedEvent, items });  //Call
		}
	}

Re: Iteraction.Trigger inside DataTemplate

Posted: 23 Sep 2021, 11:19
by sfernandez
Hi, this problem is related to this know bug: https://www.noesisengine.com/bugs/view.php?id=1476
When template gets applied, the cloned behavior is not properly registered in the namescope, so instead of returning the cloned object, it returns the behavior in the template definition.

Your approach won't work if the DataTemplate is applied to different controls at the same time, because when one of the behaviors raises the event, it will be notified to all the instances.

In the ticket I mentioned we provide a workaround, but this is something we need to fix. We'll try to solve it for next release.

Re: Iteraction.Trigger inside DataTemplate

Posted: 23 Sep 2021, 12:06
by Logrus
How to bind in this case?
                <i:Interaction.Triggers>
                    <EventTrigger EventName="???" SourceName="msb">
                        <InvokeCommandAction Command="{Binding ChangeSelectedNodesCommand}" />
                    </EventTrigger>
                </i:Interaction.Triggers>

Re: Iteraction.Trigger inside DataTemplate

Posted: 23 Sep 2021, 12:39
by sfernandez
This should the trick:
<DataTemplate DataType="{x:Type SubHierarchy}">
    <TreeView x:Name="tv" ItemContainerStyle="{StaticResource Style.SceneMultiSelectedTreeViewItem}" ItemsSource="{Binding Root.Childs}">
        <i:Interaction.Behaviors>
            <TreeViewMultipleSelectionBehavior SelectedItems="{Binding SelectedNodes, Mode=TwoWay}" />
        </i:Interaction.Behaviors>
        <i:Interaction.Triggers>
            <EventTrigger EventName="MultiSelectionChanged" SourceObject="{Binding (i:Interaction.Behaviors)[0], ElementName=tv}">
                <InvokeCommandAction Command="{Binding ChangeSelectedNodesCommand}" />
            </EventTrigger>
        </i:Interaction.Triggers>
    </TreeView>
</DataTemplate>

Re: Iteraction.Trigger inside DataTemplate

Posted: 23 Sep 2021, 13:00
by Logrus
Thanks