Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将样式应用于在gridview下找到的第一个WPF ContentPresenter,但不应用于任何更深的WPF_C#_.net_Wpf - Fatal编程技术网

C# 如何将样式应用于在gridview下找到的第一个WPF ContentPresenter,但不应用于任何更深的WPF

C# 如何将样式应用于在gridview下找到的第一个WPF ContentPresenter,但不应用于任何更深的WPF,c#,.net,wpf,C#,.net,Wpf,我希望能够设置用于渲染GridView单元格的ContentPresenter的样式。但是,如果我通常将样式设置为以ContentPresenter为目标,那么它将以ContentPresenter中的ContentPresenter实例为目标,而我不希望这样做。我只想为找到的第一级内容演示者设置样式 这可能吗?像这样的 <Style Target="GridView"> <Style.Resource> <Style Target="Con

我希望能够设置用于渲染GridView单元格的ContentPresenter的样式。但是,如果我通常将样式设置为以ContentPresenter为目标,那么它将以ContentPresenter中的ContentPresenter实例为目标,而我不希望这样做。我只想为找到的第一级内容演示者设置样式

这可能吗?像这样的

<Style Target="GridView">
    <Style.Resource>
        <Style Target="ContentPresenter" Depth=1>
            <Setter Property="Margin" Value="1"/>
        </Style>
    </Style.Resources>
</Style>

其中Depth=1是一个虚构的属性。

您可以使用DataTemplateSelector来实现这一点,方法是为ContentPresenter设置一个样式,并确保它使用了默认的样式

我的例子简化了,没有使用GridView,但概念是一样的

如果您具有以下DataTemplateSelector:

public class DepthTemplateSelector : DataTemplateSelector
{
    public DataTemplate InDepthTemplate { get; set; }

    public Type Type { get; set; }

    public int Depth { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var next = container;
        int itemsControlCount = 0;

        while (VisualTreeHelper.GetParent(next) != null)
        {
            var current = VisualTreeHelper.GetParent(next);
            if (current.GetType() == this.Type)
            {
                itemsControlCount++;
            }

            next = current;
        }



        if (itemsControlCount <= this.Depth)
        {
            return this.InDepthTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}
然后在XAML中将其与您希望用于内容演示者(深度小于某一深度)的任何模板连接起来:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:w="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <w:DepthTemplateSelector x:Key="DepthTemplateSelector" Depth="2" Type="{x:Type ContentPresenter}">
        <w:DepthTemplateSelector.InDepthTemplate>
            <DataTemplate DataType="{x:Type w:Model}">
                <StackPanel>
                    <TextBlock Text="{Binding Description}" Foreground="Red" />
                    <ItemsControl ItemsSource="{Binding Models}" Margin="20,0,0,0" />
                </StackPanel>
            </DataTemplate>
        </w:DepthTemplateSelector.InDepthTemplate>
    </w:DepthTemplateSelector>

    <Style TargetType="{x:Type ContentPresenter}">
        <Setter Property="ContentTemplateSelector" Value="{StaticResource DepthTemplateSelector}" />
    </Style>

    <DataTemplate DataType="{x:Type w:Model}">
        <StackPanel>
            <TextBlock Text="{Binding Description}" />
            <ItemsControl ItemsSource="{Binding Models}" Margin="20,0,0,0" />
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<Window.DataContext>
    <w:ViewModel />
</Window.DataContext>

<ListView ItemsSource="{Binding Models}" />
</Window>
因此XAML创建和配置DataTemplateSelector,但也通过设置默认ContentPresenter样式来确保所有ContentPresenter都使用它

这将为您提供以下效果,深度设置为2:

这基于以下视图模型,该模型使用递归结构来说明这一点:

public class ViewModel
{
    public ViewModel()
    {
        this.Models = new List<Model>
            {
                new Model
                    {
                        Description = "ModelA", 
                        Models = new List<Model>
                            {
                                new Model { Description = "ModelA1" },
                                new Model { Description = "ModelA2" }
                            }
                    },
                new Model
                    {
                        Description = "ModelB", 
                        Models = new List<Model>
                            {
                                new Model { Description = "ModelB1" },
                                new Model
                                    {
                                        Description = "ModelB2", 
                                        Models = new List<Model>
                                            {
                                                new Model { Description = "ModelB2i" },
                                                new Model { Description = "ModelB2ii" }
                                            }
                                    }
                            }
                    }
            };
    }

    public List<Model> Models { get; set; }
}

public class Model
{
    public string Description { get; set; }

    public List<Model> Models { get; set; }
}