TabItem блокируется навсегда

У меня очень странная проблема: в WPF у меня есть tabControl, который содержит 3 tabItems. Я сделал привязку из SelectedIndex tabControl к свойству внутри моего класса viewModel в режиме «OneWayToSource».

Вот код XAML:

<TabControl Name="mainTabControl" SelectedIndex="{Binding SelectedTabIndex, Mode=OneWayToSource}"  >
        <TabItem Header="Tab 01" Name="tab01"> ... </TabItem>
        <TabItem Header="Tab 02" Name="tab02"> ... </TabItem>
        <TabItem Header="Tab 03" Name="tab03"> ... </TabItem>
</TabControl>

И на мой взглядМодель:

    private int m_selectedTabIndex;
    public int SelectedTabIndex
    {
        get
        { return m_selectedTabIndex; }
        set
        {
            SetAndNotify(ref m_selectedTabIndex, value, () => SelectedTabIndex);
            SelectedTabChanged();
        }
    }

private void SelectedTabChanged()
    {
        // Some code
    }

Как видите, каждый раз, когда изменяется свойство SelectedTabIndex моей viewModel, выполняется метод SelectedTabChanged(), и это работает отлично.

Моя странная проблема заключается в следующем: Когда я показываю сообщение, используя, например, System.Windows.MessageBox.Show("Some Text") внутри моего метода SelectedTabChanged(), я выбираю другую вкладку, и предыдущая выбранная вкладка блокируется, она выглядит как выбранная, но остается выбранной постоянно, я не могу видеть ее контента больше.

Просто поясню: как я уже говорил, эта странная проблема возникает только при отображении модального окна

Почему происходит? Как я могу решить эту проблему?

Надеюсь, я ясно объяснил.

Заранее спасибо.


person Dante    schedule 19.06.2012    source источник


Ответы (2)


Я решил свою проблему. Поскольку я новичок в WPF, я действительно не понимаю, почему модальное окно блокирует вкладки. Но я искал и обнаружил, что класс Dispatcher позволяет асинхронно выполнять метод, который предотвращает блокировку любого элемента управления.

Я изменил свой код viewModel, как показано ниже:

public int SelectedTabIndex
    {
        get
        { return m_selectedTabIndex; }
        set
        {
            SetAndNotify(ref m_selectedTabIndex, value, () => SelectedTabIndex);
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(SelectedTabChanged), null);
        }
    }

Строка, которая действительно помогла мне, была следующей:

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(SelectedTabChanged), null);

Надеюсь, что эта помощь поможет кому-то еще столкнуться с подобной проблемой.

person Dante    schedule 19.06.2012

Я не на 100% уверен, что понимаю вашу проблему, но MessageBox.Show создаст вложенный поток сообщений и заблокирует основной Dispatcher, тем самым «заморозив» главное окно (поэтому оно модальное). Если вам нужно показать оповещение в стиле MessageBox, не будучи модальным, то я советую создать панель с вашим сообщением, которая существует в TabItem со скрытой видимостью, а затем сделать ее видимой, когда это необходимо, чтобы показать вам сообщение. Ваш выбор вкладки должен по-прежнему работать в этом сценарии.

person Dean Chalk    schedule 19.06.2012
comment
Спасибо за ваш ответ, но на самом деле мне нужно показать модальное окно, так как это может быть сообщение об исключении, поэтому я пытаюсь показать любое модальное окно, не блокируя вкладку. - person Dante; 19.06.2012
comment
Если он модальный, он заблокирует tabcontrol, поэтому нет возможного решения IMO. - person Dean Chalk; 19.06.2012