2

각 TabItem의 가시성에 대한 속성을 가진 ViewModel에 바인딩되는 많은 TabItems가있는 TabControl이 있습니다.Silverlight TabItem 가시성이 변경되지 않음

<sdk:TabControl> 
    <sdk:TabItem Name="Inventory" Header="Inventory" 
     Style="{StaticResource TabItemStyle}" 
     Visibility="{Binding Permissions.Inventory, 
     Converter={StaticResource PermissiveVisibilityConverter}, 
      ConverterParameter='Viewer'}" 
     DataContext="{Binding VM}" /> 

</sdk:TabControl> 

모든 TabItem의 기본값은 접기 상태입니다. 그러나 VM이 TabItem을 Visible로 변경하면 마우스를 컨트롤 위로 이동해야만 작동합니다.

버튼으로 프로그래밍 방식으로 가시성을 설정하더라도 동일한 방식으로 작동합니다!

VM의 속성이 UI 알리고 있는지 확인하고 NotifyOnPropertyChanged 함께 확인했습니다. 그리고 데이터를 단추의 가시성에 바인딩하면 잘 작동합니다 ... 그것은 버그가있는 TabItems입니다.

새로 고침하려면 TabItem UI를 가져 오는 방법이 있습니까? 또는이 문제를 해결할 수 있습니까?

감사합니다.

+0

? 권한 속성과 인벤토리 속성 모두에서 알림 속성이 변경 되었습니까? –

+0

Silverlight 5. 모두 예, TabItem이 변경 내용을 볼 때 ViewModel을 업데이트 할 때 확인했는지 확인했습니다. 단지 UI를 업데이트하지 않습니다. – tcables

+0

Hmmmmm 아주 이상 해요! 나는 Tab 컨트롤에 몇 가지 버그가 있다는 것을 알고 있으며, 스스로를 보지 않고 codeplex에서 툴킷 소스 코드를 다운로드하고 탭 컨트롤이 탭 항목의 가시성을 내부적으로 처리하는지 확인하려고한다. 죄송합니다. 쉬운 대답이 없습니다. –

답변

0

당신은 무엇을 먼저 DataContext를 설정하고 있도록 XAML 변경하는 경우 : 나는 Permissions.Inventory이보기 모델의 속성이라고 가정하지만 당신은 설정하지 않은 이후거야

<sdk:TabItem Name="Inventory" Header="Inventory" 
    Style="{StaticResource TabItemStyle}" 
    DataContext="{Binding VM}" 
    Visibility="{Binding Permissions.Inventory, 
    Converter={StaticResource PermissiveVisibilityConverter}, 
     ConverterParameter='Viewer'}" /> 

을 그 시점에서 컨텍스트는 바인딩이 작동해서는 안되는 것처럼 보입니다.

또한 중단 점을 설정하고 Permissions.Inventory의 getter가 호출되는 경우 변환기가 손상됩니까?

+0

나는 어딘가에 버튼을 놓았고, 나는 붕괴와 보이는 사이의 허락을 가볍게 치기 위해 그것을 설정했다. 그리고 그것은 datacontext를 먼저 움직이게하지 않고 작동하는 것처럼 보인다. 이 문제는 양식이 초기화 될 때만 발생하는 것으로 보입니다. – tcables

+0

접힌 상태로 초기화하고 단추로 표시되도록 설정하면 다른 탭을 클릭 할 때까지 작동하지 않습니다. 그러면 표시됩니다. 그러나 다음에 무언가를 붕괴시키고 다시 볼 수있게되면 잘 작동합니다. – tcables

3

나는 동일한 문제에 봉착했으며 원래의 "가시성"속성을 사용하여이를 극복 할 수있었습니다. 이 새 속성에서 값을 원래의 Visibility 속성에 전달할 수 있으며 부모 탭 컨트롤의 "SelectedItem"이 축소되어 다음에 표시되는 tabItem을 선택합니다.

그러나 표시된 here, TabControl로드 할 때 첫 번째 항목을 축소 할 경우에만 충분하지 않을 수 있습니다. 이 경우는 TabControl 자체에서 수정되어야합니다. 왜냐하면 테스트는 가짜 "Visility"가 TabItem에 처음 액세스하도록 설정되어 있지 않은데 아직 TabControl에 액세스하지 않았기 때문에 나타났기 때문입니다. 그 때문에이 문제를 해결하는 TabControl의 연결된 속성도 사용했습니다.

완전한 솔루션 :

public static class TabControlExtensions 
{ 
    /// <summary> 
    /// Use this property on a TabControl to correct the behavior 
    /// of selecting Collapsed TabItems. 
    /// </summary> 
    /// <param name="obj"></param> 
    /// <returns></returns> 
    public static bool GetSelectOnlyVisibleTabs(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(SelectOnlyVisibleTabsProperty); 
    } 
    public static void SetSelectOnlyVisibleTabs(DependencyObject obj, bool value) 
    { 
     obj.SetValue(SelectOnlyVisibleTabsProperty, value); 
    } 
    public static readonly DependencyProperty SelectOnlyVisibleTabsProperty = 
     DependencyProperty.RegisterAttached("SelectOnlyVisibleTabs", typeof(bool), typeof(TabControlExtensions), new PropertyMetadata(false, SelectOnlyVisibleTabsChanged)); 
    public static void SelectOnlyVisibleTabsChanged(object sender, DependencyPropertyChangedEventArgs args) 
    { 
     var tabControl = sender as TabControl; 
     if (tabControl == null) return; 

     if ((bool)args.NewValue) 
     { 
      tabControl.SelectionChanged += TabControl_SelectionChanged; 
      CorrectSelection(tabControl); 
     } 
     else 
     { 
      tabControl.SelectionChanged -= TabControl_SelectionChanged; 
     } 
    } 

    private static void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs args) 
    { 
     var tabControl = sender as TabControl; 
     if (tabControl == null) return; 

     CorrectSelection(tabControl); 
    } 

    public static void CorrectSelection(TabControl tabControl) 
    { 
     var selected = tabControl.SelectedItem as UIElement; 
     if (selected == null) return; 

     // If the selected element is not suposed to be visible, 
     // selects the next visible element 
     if (selected.Visibility == System.Windows.Visibility.Collapsed) 
      tabControl.SelectedItem = tabControl.Items.OfType<UIElement>() 
       .Where(e => e.Visibility == System.Windows.Visibility.Visible) 
       .FirstOrDefault(); 
    } 
} 

public static class TabItemExtensions 
{ 
    /// <summary> 
    /// Use this property in a TabItem instead of the original "Visibility" to 
    /// correct the behavior of a TabControl when a TabItem's Visibility changes. 
    /// </summary> 
    /// <param name="obj"></param> 
    /// <returns></returns> 
    public static Visibility GetVisibility(DependencyObject obj) 
    { 
     return (Visibility)obj.GetValue(VisibilityProperty); 
    } 
    public static void SetVisibility(DependencyObject obj, Visibility value) 
    { 
     obj.SetValue(VisibilityProperty, value); 
    } 
    public static readonly DependencyProperty VisibilityProperty = 
     DependencyProperty.RegisterAttached("Visibility", typeof(Visibility), typeof(TabItemExtensions), new PropertyMetadata(Visibility.Visible, VisibilityChanged)); 

    public static void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs args) 
    { 
     var tabItem = sender as TabItem; 
     if (tabItem == null) return; 

     var visibility = (Visibility)args.NewValue; 
     if (tabItem.Visibility == visibility) return; 

     tabItem.Visibility = visibility; 
     if (visibility == Visibility.Visible) return; 

     // Finds the tab's parent tabcontrol and corrects the selected item, 
     // if necessary. 
     var tabControl = tabItem.Ancestors().OfType<TabControl>().FirstOrDefault(); 
     if (tabControl == null) return; 

     TabControlExtensions.CorrectSelection(tabControl); 
    } 
} 

사용법 : 사용중인 SL의 어떤 버전

<sdk:TabControl local:TabControlExtensions.SelectOnlyVisibleTabs="True"> 
     <sdk:TabItem Header="tabItem1" Visibility="Collapsed"> 
      <TextBlock HorizontalAlignment="Center" 
         VerticalAlignment="Center" 
         Text="TabItem1 which should not be visible (1)" /> 
     </sdk:TabItem> 
     <sdk:TabItem Header="tabItem2"> 
      <TextBlock HorizontalAlignment="Center" 
         VerticalAlignment="Center" 
         Text="TabItem2 which should be visible (2)" /> 
     </sdk:TabItem> 
     <sdk:TabItem DataContext="{Binding ViewModel}" 
        Header="tabItem3" 
        local:TabItemExtensions.Visibility="{Binding MyProperty, 
                   Converter={StaticResource BoolToVisibilityConverter}}"> 
      <TextBlock HorizontalAlignment="Center" 
         VerticalAlignment="Center" 
         Text="TabItem with binded Visibility (3)" /> 
     </sdk:TabItem> 
    </sdk:TabControl> 
+0

아직 내 프로젝트에서 이것을 테스트했지만 견고한 것으로 보입니다. 당신의 일에 감사드립니다. :) – tcables

+0

방금 ​​사용했는데 아무런 효과가없는 문제가있었습니다. 사소한 변경 사항은 TabControl의 Loaded 이벤트에 대한 이벤트 핸들러를 추가하는 것이 었습니다. 모두로드 될 때까지 모든 가시성 속성이 아직 설정되지 않았습니다. –

+0

노력 덕분에 일했습니다. 그러나 VisibilityChanged 메서드에서 GetSelfAndAncestors로 Ancestors를 수정해야했습니다. tabItem.GetSelfAndAncestors(). OfType () .FirstOrDefault() – Ananda

관련 문제