Page 1 of 1

ClickMode for TabItem or TabControl

Posted: 24 Jun 2022, 14:45
by Joren
Hey,

I want to change the ClickMode for all our TabControls from press to release where it triggers the SelectionChanged event, so it matches the behavior with all our other elements. Perhaps this can be done through supporting ClickMode in either TabItem or TabControl. I know this is not a thing in WPF and I can't find good solutions to do it otherwise. The only way I currently see it done, is to manually implement this for every TabControl and thats not very scaleable.

So my question is, can support for this be added through the use of ClickMode or any other means? Or perhaps there is currently a better way to solve this?

Re: ClickMode for TabItem or TabControl

Posted: 27 Jun 2022, 12:02
by sfernandez
Hi Joren,

You can implement an attached property that hooks to TabItem's mouse events to manually handle the selection on MouseUp, for example:
struct TabHelper
{
    static const DependencyProperty* EnableMouseUpSelectionProperty;

    static void OnMouseDown(BaseComponent* sender, const MouseButtonEventArgs& e)
    {
        TabItem* tab = (TabItem*)sender;
        if (!tab->GetIsSelected())
        {
            e.handled = true;
        }
    }

    static void OnMouseUp(BaseComponent* sender, const MouseButtonEventArgs& e)
    {
        TabItem* tab = (TabItem*)sender;
        if (!tab->GetIsSelected())
        {
            tab->SetIsSelected(true);
            e.handled = true;
        }
    }

    NS_IMPLEMENT_INLINE_REFLECTION(TabHelper, NoParent, "Testing.TabHelper")
    {
        UIElementData* data = NsMeta<UIElementData>(TypeOf<SelfClass>());
        data->RegisterProperty<bool>(EnableMouseUpSelectionProperty, "EnableMouseUpSelection",
            PropertyMetadata::Create<bool>(false, PropertyChangedCallback(
        [](DependencyObject* d, const DependencyPropertyChangedEventArgs& e)
        {
            TabItem* tab = DynamicCast<TabItem*>(d);
            if (tab != nullptr)
            {
                if (e.NewValue<bool>())
                {
                    tab->PreviewMouseLeftButtonDown() += OnMouseDown;
                    tab->MouseLeftButtonUp() += OnMouseUp;
                }
                else
                {
                    tab->PreviewMouseLeftButtonDown() -= OnMouseDown;
                    tab->MouseLeftButtonUp() -= OnMouseUp;
                }
            }
        })));
    }
};
Then you can set the property in the style of your theme's TabItem to change the behavior on all the tabs:
<Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
  <Setter Property="local:TabHelper.EnableMouseUpSelection" Value="True"/>
  ...
</Style>

Re: ClickMode for TabItem or TabControl

Posted: 27 Jun 2022, 13:01
by Joren
Thanks! This is way better than what I would have come up with.

Re: ClickMode for TabItem or TabControl

Posted: 27 Jun 2022, 13:14
by sfernandez
Glad to help, marking this as solved.