Tôi đã ngừng phát hành vấn đề này một lúc và chỉ tìm thấy một phần của giải pháp.TabControl- ngăn cản người dùng thay đổi tab đã chọn: MessageBox gây lỗi
Tôi đang cố gắng thiết lập TabControl để tôi có thể trong một số trường hợp ngăn người dùng thay đổi tab hiện được chọn. Khi người dùng bị ngăn thay đổi tab hiện đang được chọn, khi đó họ được hiển thị một hộp thoại.
Tôi đã đọc các tài liệu sau:
- WPF - reset ListBox scroll position when ItemsSource changes
- http://wizardsofsmart.net/uncategorized/itemssourcechanged-event-using-attached-dependency-properties/
- http://joshsmithonwpf.wordpress.com/2009/09/04/how-to-prevent-a-tabitem-from-being-selected/
- http://social.expression.microsoft.com/Forums/en-US/wpf/thread/f7b46018-1e97-4bbe-ada8-49b75dbc1da2/
tôi đã thực hiện các giải pháp đã nêu trong các liên kết thứ 3 (mặc dù tất cả ở trên tạo ra cùng một lỗi een dưới đây). Và nó hoạt động, nhưng ...
Mọi thứ lộn xộn lên triệt để nếu người dùng nào sau đây:
- nỗ lực để thay đổi tab khi một hành động như vậy là không được phép. MessageBox bật lên với lỗi.
- người dùng nhấp "OK" và được trả lại cửa sổ ban đầu.
- người dùng thử lại để thay đổi tab. Không có MessageBox nào xuất hiện.
- nếu người dùng thu nhỏ cửa sổ và sau đó phóng to lại cửa sổ, thì Hộp thư được cho là xuất hiện trước đó sẽ xuất hiện.
- người dùng nhấp "OK" và được trả lại cửa sổ gốc ... nhưng tab đã được thay đổi thành tab trước đây, mặc dù họ không thể thay đổi tab.
Điều này rõ ràng là không hành vi lý tưởng. Tại sao MessageBox không xuất hiện lần thứ hai và tại sao tab lại thay đổi khi không được phép làm như vậy?
Nếu tôi xóa phần MessageBox, nó hoạt động tốt.
Đây là mã cho xử lý sự kiện TabControl.SelectionChanged:
bool _isChanging = false;
private void tabControlForNavigation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isChanging && canChangeTabs.IsChecked.HasValue)
{
_isChanging = true;
bool canLeave = canChangeTabs.IsChecked.Value; //normally this would be replaced by a check in the ViewModel
if (!canLeave)
{
int prevIndex = tabControlForNavigation.Items.IndexOf(tabControlForNavigation.SelectedContent);
tabControlForNavigation.SelectedIndex = prevIndex;
MessageBox.Show("Can't change tabs!"); //if I comment out this line, everything works fine.
}
_isChanging = false;
}
}
Tôi đang sử dụng MVVM để thực hiện điều này. Window trông như thế này:
<Window x:Class="TestTabControlSwitching.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox x:Name="canChangeTabs"
Content="Can Change Tabs"
IsChecked="True" />
<TabControl x:Name="tabControlForNavigation"
Grid.Row="1"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Collection}"
SelectedItem="{Binding SelectedItem}"
SelectionChanged="tabControlForNavigation_SelectionChanged"
Margin="4"
HorizontalAlignment="Stretch">
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</Grid>
tôi bỏ qua phần còn lại của mã cho lợi ích của brevity- có một cấu trúc ViewModel khá thẳng về phía trước sao lưu các cửa sổ.
Chúng tôi có biết đây có phải là lỗi trong WPF không? Hay là vì một lý do kỳ lạ nào đó "do thiết kế"? – skybluecodeflier
Tôi không chắc chắn, tìm kiếm lý do cho điều này bản thân mình một vài năm trở lại nhưng không bao giờ tìm thấy bất kỳ thông tin. Chỉ cần nhìn vào nó với Reflector nhưng nó phức tạp để nói những gì đang xảy ra .. –