Preventing tab changes for TabControl
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
If we have a `TabControl` in a WPF application and we'd like to allow or not tab changes, the best way we can actually do it is by having an attached property like the following :
```cs
public static partial class TabControlHelper
{
public static readonly DependencyProperty PreventTabChangeProperty = DependencyProperty.RegisterAttached("PreventTabChange", typeof(bool), typeof(TabControlHelper), new PropertyMetadata(false, OnPreventTabChangeChanged));
public static bool GetPreventTabChange(TabControl tabControl)
{
return (bool)tabControl.GetValue(PreventTabChangeProperty);
}
public static void SetPreventTabChange(TabControl tabControl, bool value)
{
tabControl.SetValue(PreventTabChangeProperty, value);
}
private static void OnPreventTabChangeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool preventTabChanges && d is TabControl tabControl)
{
if (preventTabChanges)
{
tabControl.SelectionChanged += TabControl_SelectionChanged;
}
else
{
tabControl.SelectionChanged -= TabControl_SelectionChanged;
}
}
}
private static void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is TabControl tabControl && e.RemovedItems.Count > 0)
{
int prevIdx = tabControl.Items.IndexOf(e.RemovedItems[0]);
if (prevIdx != -1)
{
tabControl.SelectionChanged -= TabControl_SelectionChanged;
tabControl.SelectedIndex = prevIdx;
tabControl.SelectionChanged += TabControl_SelectionChanged;
}
}
}
}
```
It prevents tab changes properly but it has side effects : because of `tabControl.SelectedIndex = prevIdx;`, `Selector.SelectionChanged` is raised. Moreover the initial tab change won't be really prevented, it'll just be reverted and that means the initial `Selector.SelectionChanged` is also triggered. In the end, the tab change has been properly "prevented" but `Selector.SelectionChanged` is raised twice which is obviously not what we want.
I'm not sure about what's the best way to implement this in WPF, I think the most natural to me would be having a boolean dependency property usable like the above attached property but without the side effects or a PreviewSelectionChanged event that allows me to cancel the change via args... As long as tab changes can be prevented without side effects it's good.
Contributor guide
Assessment
This issue has not been assessed yet.