Переключение шаблонов TabControl в зависимости от свойства - PullRequest
1 голос
/ 17 января 2020

Я хочу переключить ItemTemplate и ContentTemplate TabControl. Поэтому я создал два DataTemplates для TabItem и два DataTemplates для TabContent. Шаблоны должны переключаться, если свойство IsRunningSession в CcLoginViewModel имеет значение true. Моя проблема заключается в том, как получить доступ к этому свойству в DataTrigger.

Xaml:

    <DataTemplate x:Key="LoginContentDataTemplate" x:Name="LoginTemplate" DataType="{x:Type vm:CcPlayerViewModel}">
        <local:CcLoginControl x:Name="LoginContentTemplate" DataContext="{Binding Login}" />
    </DataTemplate>
    <DataTemplate x:Key="PlayerContentDataTemplate" DataType="{x:Type vm:CcPlayerViewModel}">
        <local:CcPlayerControl x:Name="PlayerContentDataTemplate" DataContext="{Binding}" />
    </DataTemplate>

    <Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
        <Setter Property="ContentTemplate" Value="{StaticResource LoginContentDataTemplate}" />
        <Setter Property="ItemTemplate" Value="{StaticResource TabControlNewItemDataTemplate}" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding Login.IsRunningSession, Source={StaticResource PlayerTabItemTemplate}}" Value="True">  <-- Binding?
                <Setter Property="ContentTemplate" Value="{StaticResource PlayerContentDataTemplate}" />
                <Setter Property="ItemTemplate" Value="{StaticResource PlayerTabItemTemplate}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding DataContext.Players/Login.IsRunningSession, ElementName=TabControlPlayers}" Value="False">  <-- Binding?
                <Setter Property="ContentTemplate" Value="{StaticResource LoginContentDataTemplate}" />
                <Setter Property="ItemTemplate" Value="{StaticResource TabControlNewItemDataTemplate}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Window.DataContext>
    <vm:CcMainViewModel x:Name="MainViewModel" />
</Window.DataContext>

<Grid>
    <TabControl Name="TabControlPlayers"
                ItemsSource="{Binding Players}"
                Style="{DynamicResource TabControlStyle}"/>
</Grid>

ViewModels:

public class CcMainViewModel : CcViewModelBase
{
    public ObservableCollection<CcPlayerViewModel> Players { get; set; }
}

 public class CcPlayerViewModel : CcViewModelBase
{
    public CcLoginViewModel Login { get; set; }
}

public class CcLoginViewModel : CcViewModelBase
{
     public string Name
    {
        get { return name; }
        set
        {
            if (name != value)
            {
                name = value;
                OnPropertyChanged();
            }
        }
    }

    public string Password
    {
        get { return password; }
        set
        {
            if (password != value)
            {
                password = value;
                OnPropertyChanged();
            }
        }
    }

    public bool IsRunningSession
    {
        get { return isRunningSession; }
        set
        {
            if (isRunningSession != value)
            {
                isRunningSession = value;
                OnPropertyChanged();
            }
        }
    }
}

1 Ответ

1 голос
/ 19 января 2020

Вы можете использовать DataTemplateSelector, как сказал Эльдар. Я добавил несколько фрагментов кода для начала.

Шаг 1 - Создайте класс, унаследовав DataTemplateSelector, как показано ниже,

public class TabControlContentTemplateSelector : DataTemplateSelector
{
    public DataTemplate LoginContentDataTemplate { get; set; }

    public DataTemplate PlayerContentDataTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var obj = item as CcPlayerViewModel;
        if (obj != null)
        {
            if(obj.Login.IsRunningSession)
            {
                return PlayerContentDataTemplate;
            }
        }

        return LoginContentDataTemplate;
    }
}

Шаг 2 - Создайте еще один класс с именем "TabControlItemTemplateSelector", который наследуется от "DataTemplateSelector", как показано ниже,

public class TabControlItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate TabControlNewItemDataTemplate { get; set; }

    public DataTemplate PlayerTabItemTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var obj = item as CcPlayerViewModel;
        if (obj != null)
        {
            if(obj.Login.IsRunningSession)
            {
                return PlayerTabItemTemplate;
            }
        }

        return TabControlNewItemDataTemplate ;
    }
}

Шаг 3 - Создайте TemplateSelectors в вашем .xaml, как показано ниже,

<local:TabControlContentTemplateSelector x:Key="TabControlItemTemplateSelector"
  LoginContentDataTemplate="{StaticResource LoginContentDataTemplate}"
  PlayerContentDataTemplate="{StaticResource PlayerContentDataTemplate}" />

    <local:TabControlItemTemplateSelector x:Key="TabControlContentTemplateSelector"
      TabControlNewItemDataTemplate="{StaticResource TabControlNewItemDataTemplate}"
       PlayerTabItemTemplate="{StaticResource PlayerTabItemTemplate}" />

Шаг 4 - Используйте оба вышеупомянутых TemplateSelectors и назначьте их вашему TabControl, как показано ниже в вашем .xaml

<TabControl Name="TabControlPlayers" ItemsSource="{Binding Players}"
            ItemTemplateSelector="{StaticResource TabControlItemTemplateSelector}"
            ContentTemplateSelector="{StaticResource TabControlContentTemplateSelector}"/>

Примечание: - В этом случае вы не используете ваш существующий "TabControlStyle", пока вы не сделаете что-то еще для TabControl.

Ваш существующий DataContext все еще может нормально работать.

Попробуйте и позвольте нам известно, если у вас возникнут какие-либо проблемы.

...