Accendo / Publikované

WPF How to prevent TabControl selection

Autor:  Libor Bešenyi

Dátum:  8.12.2011

 

I needed to prevent TabControl selection. There is only event SelectionChanged and I had lot of problems with changing SelectedItem in this event (ticking to tab and still canceling confirmation sometimes ignore event and confirmation dialog was not shown). For example I needed to confirm from user his choice to select new tab.

The more difficult problem created usage of pictures in tab headers. So I was not able to identify TabItem by Header text, because there were UI Controls… For this reason I identify click on TabItem first. However click on TabItem could be from content placeholder (there are UI elements too). So I needed to find TabItem instance and compare with current selected TabItem. If was different I could know, it is attempt to select different Tab (header click). Handling click (e.Handled = Dialog = No) in combination with modal dialog was without success – so I do it manually:

 

<TabControl Name="tabControl">

        <TabItem PreviewMouseLeftButtonDown="TabItem_PreviewMouseLeftButtonDown">

                <TabItem.Header>

                        <TextBlock>Text a</TextBlock>

                </TabItem.Header>

                <DockPanel>

                        <ListBox Background="AliceBlue" />

                </DockPanel>

        </TabItem>

 

        <TabItem PreviewMouseLeftButtonDown="TabItem_PreviewMouseLeftButtonDown">

                <TabItem.Header>

                        <TextBlock>Text a</TextBlock>

                </TabItem.Header>

                <DockPanel>

                        <ListBox Background="Black" />

                </DockPanel>

        </TabItem>

 

        <TabItem PreviewMouseLeftButtonDown="TabItem_PreviewMouseLeftButtonDown">

                <TabItem.Header>

                        <TextBlock>Text a</TextBlock>

                </TabItem.Header>

                <DockPanel>

                        <ListBox Background="Red" />

                </DockPanel>

        </TabItem>

</TabControl>

 

C#:

 

private void TabItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

        var newTab = FindFirstParent<TabItem>(sender as FrameworkElement);

        if (newTab != tabControl.SelectedItem)

        {

                e.Handled = true;

 

                if (MessageBox.Show("Really?", string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes)

                        tabControl.SelectedItem = newTab;

        } // if

}

 

public static T FindFirstParent<T>(FrameworkElement control) where T : FrameworkElement

{

        if (control == null)

                return null;

 

        if (control is T)

                return (T)control;

 

        return FindFirstParent<T>(control.Parent as FrameworkElement);

}