2010-08-26 43 views
7

Tôi có một TabControl trên UserControl được hỗ trợ bởi ViewModel và Visibility của một trong các mục tab được gắn với thuộc tính trên ViewModel.WPF TabControl - Chọn tab khác khi TabItem Hiển thị thay đổi

<TabControl x:Name="myTabControl"> 
    <TabItem Header="Tab 1" /> 
    <TabItem Header="Tab 2" Visibility="{Binding HasData, Converter={StaticResource boolToVisibilityConverter}}"/> 
</TabControl> 

Khi Visibility của TabItem thay đổi, nó sụp đổ (da) các TabItem tiêu đề, nhưng nó vẫn tiếp tục hiển thị nội dung của nó.

Tôi muốn TabControl sang chuyển sang tab hiển thị khi tab khác bị ẩn và hơi ngạc nhiên khi biết rằng điều đó không xảy ra tự động.

Gắn một event handler cho sự kiện SelectionChanged của TabControl cho thấy TabItem.IsSelected (và TabControl.SelectedItem) thậm chí còn không bị ảnh hưởng khi TabItem.Visibility thay đổi (điều này là một lỗi ?!).

Tôi đã thử cả hai kích hoạt tài sản:

<!-- This doesn't compile because of TargetName on the Setter, think you can only use it in Control Templates. 
     I don't know how to refer to the parent TabControl from within the TabItem style. --> 
    <TabControl.ItemContainerStyle> 
     <Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}"> 
      <Style.Triggers> 
       <Trigger Property="Visibility" Value="Collapsed"> 
        <Setter TargetName="myTabControl" Property="SelectedIndex" Value="0" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </TabControl.ItemContainerStyle> 

dữ liệu kích hoạt:

<!-- This doesn't quite work, it affects the Visibility of the TabItem's content too --> 
    <TabControl.Style> 
     <Style TargetType="{x:Type TabControl}" BasedOn="{StaticResource {x:Type TabControl}}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Path=SelectedItem.Visibility, ElementName=tabControl}" 
          Value="Collapsed"> 
        <Setter Property="SelectedIndex" Value="0" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TabControl.Style> 

tôi có thể không nhận được những nguyên nhân để làm việc, và không có VisibilityChanged sự kiện tôi có thể xử lý, vì vậy tôi bị mắc kẹt và sẽ đánh giá cao một số trợ giúp.

Trả lời

4

Lớp TabItem có sự kiện IsVisibleChanged mà bạn có thể sử dụng.

+0

Ah, điều đó sẽ làm! (+1) Không biết tại sao tôi không phát hiện ra nó sớm hơn - tôi đoán MSDN phải lọc ra các thuộc tính kế thừa vào thời điểm đó. Tôi sẽ ngừng đánh dấu đây là câu trả lời chỉ để xem liệu có ai đó có đề xuất không viết mã, nhưng cảm ơn bạn rất nhiều. – Riko

2

Liên kết SelectedIndex của TabControl với thuộc tính. Và thay đổi giá trị của thuộc tính này thành chỉ mục của tab mà bạn muốn hiển thị bất cứ khi nào bạn thay đổi chế độ hiển thị thành sự sụp đổ của mục tab.

1

Bạn có thể thêm trình xử lý sự kiện này vào mã phía sau. Nó sẽ kiểm tra kiểm soát của bạn ở nơi đầu tiên và thay đổi để hiển thị tab do các ràng buộc.

Thay vì thực hiện việc này, Tải lên tất nhiên, nó có ý nghĩa tổng thể để đưa điều này vào Thuộc tính đính kèm. (Tự động lựa chọn?) . Mã này giống nhau. Bạn được gọi ở nơi đầu tiên và đính kèm các sự kiện vào IsVisibleChanged. Sau đó, mẹo duy nhất là sử dụng một lambda (tham số ràng buộc) để có được cá thể TabControl vào sự kiện gọi lại. Tôi đăng giải pháp này, vì nó ngắn hơn.

private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e) 
{ 
    var tabControl = (TabControl) sender; 
    // register visibility changed to react on changes 
    foreach (TabItem item in tabControl.Items) 
    { 
     item.IsVisibleChanged += (mSender, ev) => item_IsVisibleChanged(mSender, ev, tabControl); 
    } 
    // if current selected tab is invisible, find and select first visible one. 
    if (!((TabItem) tabControl.SelectedItem).IsVisible) 
    { 
     foreach (TabItem item in tabControl.Items) 
     { 
      if (item.IsVisible) 
      { 
       tabControl.SelectedItem = item; 
       return; 
      } 
     } 
    } 
} 

private static void item_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e, TabControl tabControl) 
{ 
    // just became IsVisible = false 
    if ((bool)e.NewValue == false) 
    { 
     if (tabControl == null) return; 
     ItemCollection items = tabControl.Items; 
     foreach (UIElement item in items) 
     { 
      if (item.IsVisible) 
      { 
       tabControl.SelectedItem = item; 
       return; 
      } 
     } 
    } 
} 
Các vấn đề liên quan