Joren
Topic Author
Posts: 18
Joined: 12 Nov 2019, 15:33

ClickMode for TabItem or TabControl

24 Jun 2022, 14:45

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?
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: ClickMode for TabItem or TabControl

27 Jun 2022, 12:02

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>
 
Joren
Topic Author
Posts: 18
Joined: 12 Nov 2019, 15:33

Re: ClickMode for TabItem or TabControl

27 Jun 2022, 13:01

Thanks! This is way better than what I would have come up with.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: ClickMode for TabItem or TabControl

27 Jun 2022, 13:14

Glad to help, marking this as solved.

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 36 guests