2012-03-22 54 views
2

我有很多的TabItems結合到針對每個TabItem的可見性特性的視圖模型一個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到可見它不工作,直到你將鼠標移到控制...

即使我有一個按鈕,它的工作方式設置的知名度編程!

我已檢查,看看虛擬機的性能通知UI,以及它們與NotifyOnPropertyChanged。如果我將數據綁定到按鈕的可見性,它的工作原理就好了......這只是TabItems,似乎有一個錯誤。

有沒有辦法讓TabItem UI刷新?或者爲此做一個解決方法?

謝謝!

+0

什麼版本SL您使用的是?是否在「權限」屬性和「庫存」屬性上更改通知屬性? – 2012-03-22 15:57:43

+0

Silverlight 5.對於兩者都是,我檢查是否更新ViewModel,如果TabItem看到更改並且確實如此。它只是不更新​​用戶界面。 – tcables 2012-03-22 16:42:42

+0

嗯,非常奇怪!我知道Tab控件確實有一些缺陷,但是我自己可以建議的唯一的事情就是從codeplex下載工具包源代碼,並嘗試查看tab控件是否在內部處理選項卡項目的可見性?對不起,我沒有一個簡單的答案你 – 2012-03-22 16:56:01

回答

0

如果你改變了XAML讓你第一次設置的DataContext:

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

我假設Permissions.Inventory是您的視圖模型中的財產,但因爲你還沒有設置在這一點上下文看起來像綁定不應該工作。

此外,如果您設置一個斷點,如果在Permissions.Inventory吸氣劑被稱爲正在熱播的轉換?

+0

我在某處放置了一個按鈕,並將其設置爲輕彈摺疊狀態和可見狀態之間的權限,並且似乎無需移動datacontext即可首先設置。這個問題似乎只發生在表單初始化時。 – tcables 2012-03-23 17:45:14

+0

如果我將它初始化爲摺疊狀態,然後使用按鈕將其設置爲可見狀態,則它將不起作用,直到您單擊另一個選項卡 - 然後纔會彈出可見狀態。但下一次你將它設置爲摺疊狀態,然後重新顯示它就可以正常工作。 – tcables 2012-03-23 17:52:36

3

我面臨同樣的問題,我用所附的「可見性」屬性,而不是原來的人能夠戰勝它。在這個新屬性中,我可以將值傳遞給原始的「可見性」屬性,並且如果正在摺疊父標籤控件的「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); 
    } 
} 

用法:

<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 2012-11-08 22:32:57

+0

所以我只是用這個,並有一個問題,它根本沒有任何影響。我需要做的小改動是爲TabControl的Loaded事件添加一個事件處理程序。在全部加載之前,尚未設置所有可見性屬性。 – 2013-12-04 21:42:40

+0

它的工作表示感謝。但是必須在VisibilityChanged方法 tabItem.GetSelfAndAncestors()。OfType ().FirstOrDefault()中將祖先修改爲GetSelfAndAncestors。 – Ananda 2014-04-11 12:41:25