WPF: скрытие элемента вкладки в элементе управления вкладками, привязанным к наблюдаемой коллекции - PullRequest
3 голосов
/ 27 августа 2009

У меня есть элемент управления вкладками, привязанный к наблюдаемой коллекции для динамических вкладок следующим образом:

<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>

Таким образом, заголовки и содержимое вкладок определяются динамически и присваиваются как наблюдаемые изменения коллекции. Теперь я хотел бы скрыть некоторые вкладки, не удаляя их в коллекции позади - чтобы сохранить данные, если вкладка откроется снова.

В идеале каждая модель представления вкладки чата имеет свойство IsVisible, которое по умолчанию имеет значение true. Однако где я могу связать такое свойство, чтобы свернуть элемент табуляции?

Ответы [ 3 ]

6 голосов
/ 27 августа 2009

Если вы можете изменить ваш vm:TabViewModel, я должен изменить ваш IsVisible на свойство Visibility и использовать следующий ContentTemplate:

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

В противном случае вы можете использовать конвертер для изменения логического значения IsVisible на перечисление Visibility:

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
    }
}

Включите пространство имен в вашем xaml (ваш корневой элемент, Window в этом примере):

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

А в ваших ресурсах:

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

И, наконец, переплет:

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

Я думаю, вот и все:)

Редактировать: Ow и изменить ConverterParameter на Visibility. Свернуть на Visibility. Скрытый для скрытого;)

4 голосов
/ 11 ноября 2009

Получил правильный ответ с помощью этого ответа

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

Используйте System.Windows.Controls.BooleanToVisibilityConverter для преобразования из bool в Visibilty.

Предложение Скотта об использовании CollectionView также многообещающе.

1 голос
/ 27 августа 2009

Я предлагаю использовать CollectionView . Это что-то вроде абстрактного представления коллекции, где вы можете увидеть ее отфильтрованную часть. Связываясь с CollectionView, а не с самой коллекцией, вы сможете видеть только те, которые вам нужны, а коллекция все еще находится в фоновом режиме.

...