【问题标题】:Switching TabControl Templates depending on a property根据属性切换 TabControl 模板
【发布时间】:2020-05-04 10:48:33
【问题描述】:

我想切换 TabControl 的 ItemTemplate 和 ContentTemplate。 因此,我为 TabItem 创建了两个 DataTemplate,为 TabContent 创建了两个 DataTemplate。 如果 CcLoginViewModel 中的 IsRunningSession 属性为真,则模板应切换。 我的问题是如何在 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>

视图模型:

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();
            }
        }
    }
}

【问题讨论】:

标签: c# wpf datatemplate datatrigger


【解决方案1】:

您可以像 Eldar 所说的那样使用 DataTemplateSelector。我已经添加了一些代码 sn-ps 供您开始使用。

第 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 步 - 在您的 .xaml 中创建 TemplateSelectors,如下所示,

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

注意:-在这种情况下,在您为 TabControl 做更多事情之前,您现有的“TabControlStyle”是没有用的。

您现有的 DataContext 仍然可以正常工作。

试一试,如果您遇到任何其他问题,请告诉我们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多