2009-08-27 48 views
3

我有绑定到一个ObservableCollection动态选项卡的选项卡控制选项卡控件这就是一个标签项如下:WPF:躲在绑定到一个观察集合

<TabControl ItemsSource="{Binding AllTabs}" SelectedIndex="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
        <!--.............. --> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 

     <TabControl.ContentTemplate> 
      <DataTemplate DataType="{x:Type vm:TabViewModel}"> 
       <c:MyTabItem/> 
      </DataTemplate> 
     </TabControl.ContentTemplate> 
    </TabControl> 

所以,标签的标题和内容定义动态地分配为可观察的集合更改。现在,我想隐藏一些标签而不在后面的集合中删除它们 - 为了在标签重新打开时保持数据。

理想情况下,每个聊天选项卡viewmodel具有默认情况下设置为true的IsVisible属性。然而,我在哪里绑定这样一个属性,以使一个标签项目崩溃?

回答

6

如果你可以修改你vm:TabViewModel我要你的可见性更改为可见性属性,并使用下面的ContentTemplate:

<TabControl.ContentTemplate> 
    <DataTemplate DataType="{x:Type vm:TabViewModel}"> 
     <c:MyTabItem Visibility={Binding Visibility}/> 
    </DataTemplate> 
</TabControl.ContentTemplate> 

否则,你可以使用一个转换为布尔ISVISIBLE更改为能见度枚举:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Data; 
using System.Windows; 

namespace Something.Converters 
{ 
    [ValueConversion(typeof(bool), typeof(Visibility))] 
    public class BoolToVisibilityConverter : IValueConverter 
    { 

     #region IValueConverter Members 
     /// <summary> 
     /// Converts a value. 
     /// </summary> 
     /// <param name="value">The value produced by the binding source.</param> 
     /// <param name="targetType">The type of the binding target property.</param> 
     /// <param name="parameter">The converter parameter to use.</param> 
     /// <param name="culture">The culture to use in the converter.</param> 
     /// <returns> 
     /// A converted value. If the method returns null, the valid null value is used. 
     /// </returns> 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value is bool && targetType == typeof(Visibility)) 
      { 
       bool val = (bool)value; 
       if (val) 
        return Visibility.Visible; 
       else 
        if (parameter != null && parameter is Visibility) 
         return parameter; 
        else 
         return Visibility.Collapsed; 
      } 
      throw new ArgumentException("Invalid argument/return type. Expected argument: bool and return type: Visibility"); 
     } 

     /// <summary> 
     /// Converts a value. 
     /// </summary> 
     /// <param name="value">The value that is produced by the binding target.</param> 
     /// <param name="targetType">The type to convert to.</param> 
     /// <param name="parameter">The converter parameter to use.</param> 
     /// <param name="culture">The culture to use in the converter.</param> 
     /// <returns> 
     /// A converted value. If the method returns null, the valid null value is used. 
     /// </returns> 
     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value is Visibility && targetType == typeof(bool)) 
      { 
       Visibility val = (Visibility)value; 
       if (val == Visibility.Visible) 
        return true; 
       else 
        return false; 
      } 
      throw new ArgumentException("Invalid argument/return type. Expected argument: Visibility and return type: bool"); 
     } 
     #endregion 
    } 
} 

Inculde在XAML命名空间(您的根元素,窗口在本示例):

<Window xmlns:converters="clr-namespace:Something.Converters" 
.../> 

而在你的资源:

<Window.Resources> 
    <converters:BoolToVisibilityConverter x:Key="boolToVisibilityConverter"/> 
</Window.Resources> 

而且finaly绑定:

<TabControl.ContentTemplate> 
    <DataTemplate DataType="{x:Type vm:TabViewModel}"> 
     <c:MyTabItem Visibility={Binding IsVisible, Converter={StaticResource boolToVisibilityConverter}, ConverterParameter=Visibility.Collapsed}/> 
    </DataTemplate> 
</TabControl.ContentTemplate> 

我认为是它:)

编辑:嗷,改变ConverterParameter到Visibility.Collapsed能见度。隐藏起来;)

+0

完美运作!谢谢:) – bluebit 2009-08-28 08:40:45

+1

我试过这种确切的情况,但它只是使TabItem的内容崩溃。有任何想法吗? – Jordan 2014-01-22 21:08:54

1

我建议使用CollectionView。这有点像一个集合的抽象视图,你可以看到它的一个过滤部分。通过绑定到CollectionView而不是集合本身,你应该只能看到你想要的,而集合仍然在后台。

+0

CollectionView绝对是一个选项,但如果列表动态更改(即项目被添加,删除或更新),我们无法使用CollectionView。在这些情况下,绑定可见性是唯一的选择。对于静态集合,CollectionView是最好的解决方案。 – Amit 2011-12-14 14:38:15

0

我试过了,但没有得到预期的结果。在TabControl.ContentTemplate中绑定可见性的以下方法会导致隐藏选项卡的内容而不隐藏选项卡标题本身。

<TabControl.ContentTemplate> <DataTemplate DataType="{x:Type vm:TabViewModel}"> <c:MyTabItem Visibility={Binding Visibility}/> </DataTemplate> </TabControl.ContentTemplate>

仍然战斗了隐藏选项卡标题本身。

4

得到了正确的答案与this answer

<TabControl.ItemContainerStyle> 
    <Style TargetType="{x:Type TabItem}"> 
    <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource boolToVisibilityConverter}"/> 
    </Style> 
</TabControl.ItemContainerStyle> 

的帮助下从BOOL到使用公开程度为转换System.Windows.Controls.BooleanToVisibilityConverter。

Scott对使用CollectionView的建议也很有前途。