C# WPF树查看整行的项目背景

C# WPF树查看整行的项目背景,c#,wpf,treeview,wpf-controls,treeviewitem,C#,Wpf,Treeview,Wpf Controls,Treeviewitem,我正在编写一个应用程序,我需要在整行下按项目设置背景。我在中找到了一些灵感,但我不知道如何在模板中获取边框背景值(问题有点复杂:) 我的问题是树视图中有两种类型的“数据”(文件和文件夹)。用户可以在“文件和文件夹”下修改背景 现在我在textblock上有背景,但它看起来很糟糕,我希望整行都有背景(我认为它看起来会更好) 现在看来是这样: 但我需要的是: 如果更改边框背景的值,则会更改所有项目(逻辑上)。所以我想我真的需要使用textblock背景,但我无法覆盖整行(stretch不是一个解

我正在编写一个应用程序,我需要在整行下按项目设置背景。我在中找到了一些灵感,但我不知道如何在模板中获取边框背景值(问题有点复杂:)

我的问题是树视图中有两种类型的“数据”(文件和文件夹)。用户可以在“文件和文件夹”下修改背景

现在我在textblock上有背景,但它看起来很糟糕,我希望整行都有背景(我认为它看起来会更好)

现在看来是这样:

但我需要的是:

如果更改边框背景的值,则会更改所有项目(逻辑上)。所以我想我真的需要使用textblock背景,但我无法覆盖整行(stretch不是一个解决方案,因为它只将文本块扩展到行的末尾,而不是之前的空白)

谢谢你的建议

编辑:此处的XAML:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:treeView">
<!-- TREEVIEW  -->
    <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
        <Setter Property="Focusable" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ToggleButton">
                    <Grid
          Width="15"
          Height="13"
          Background="Transparent">
                        <!--<Path x:Name="ExpandPath"
            HorizontalAlignment="Left" 
            VerticalAlignment="Center" 
            Margin="1,1,1,1"
            Fill="Red"
            Data="M 4 0 L 8 4 L 4 8 Z"/>-->
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked"
               Value="True">
                            <!--<Setter Property="Data"
                TargetName="ExpandPath"
                Value="M 0 4 L 8 4 L 4 8 Z"/>-->
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="TreeViewItemFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border>
                        <Rectangle Margin="0,0,0,0"
                 StrokeThickness="5"
                 Stroke="Black"
                 StrokeDashArray="1 2"
                 Opacity="0"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
        <Setter Property="Padding" Value="1,0,0,0"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TreeViewItem}">
                    <ControlTemplate.Resources>
                        <local:LeftMarginMultiplierConverter Length="19" x:Key="lengthConverter" />
                    </ControlTemplate.Resources>
                    <StackPanel>
                        <Border x:Name="Bd"
                          Background="{TemplateBinding Background}"
                          BorderBrush="{TemplateBinding BorderBrush}"
                          BorderThickness="{TemplateBinding BorderThickness}"
                          Padding="{TemplateBinding Padding}">
                            <Grid Margin="{Binding Converter={StaticResource lengthConverter}, RelativeSource={RelativeSource TemplatedParent}}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="19" />
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <ToggleButton Grid.Column="1" x:Name="Expander"
                                  Style="{StaticResource ExpandCollapseToggleStyle}"
                                  IsChecked="{Binding Path=IsExpanded,
                                              RelativeSource={RelativeSource TemplatedParent}}"
                                  ClickMode="Press"/>
                                <ContentPresenter x:Name="PART_Header" Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ContentSource="Header" />
                            </Grid>
                        </Border>
                        <ItemsPresenter x:Name="ItemsHost" />
                    </StackPanel>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsExpanded" Value="false">
                            <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="HasItems" Value="false">
                            <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HasHeader" Value="false"/>
                                <Condition Property="Width" Value="Auto"/>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="HasHeader" Value="false"/>
                                <Condition Property="Height" Value="Auto"/>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/>
                        </MultiTrigger>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

使用snoop了解您试图修改的可视树。这样就需要2-3分钟才能真正了解需要修改的内容。(谷歌)

我敢打赌,你需要使用这样的东西:

<TreeView>
<TreeView.ItemContainerStyle>
<Style BasedOn="{StaticResource {x:Type TreeViewItem}}" TargetType="TreeViewItem">
                    <Setter Property="Background" Value="Purple" />
</TreeView.ItemContainerStyle>
</TreeView>


如果您需要背景颜色,还需要添加触发器,具体取决于项目。

感谢您的解决方案!以下是我到目前为止所做的预览:


public class LeftMarginMultiplierConverter : IValueConverter
    {
        public int Length { get; set; }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Thickness thickness = new Thickness(0, 0, 0, 0);
            if (value != null)
            {
                TreeViewItem treeViewItem = (TreeViewItem)value;
                ItemsControl parent = ItemsControl.ItemsControlFromItemContainer(treeViewItem);
                if (parent != null)
                {
                    if (parent.GetType() == typeof(TreeView))
                    {
                        thickness = new Thickness(System.Convert.ToDouble(Length), 5, 5, 5);
                    }
                    else if (parent.GetType() == typeof(TreeViewItem))
                    {
                        Grid grid = (Grid) Helper.GetChildOfType<Grid>(parent);
                        if(grid != null)
                            thickness = new Thickness(System.Convert.ToDouble(grid.Margin.Left + Length), 5, 5, 5);
                    }
                }
            }
            return thickness;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public static class Helper
    {
        public static T GetChildOfType<T>(this DependencyObject depObj) where T : DependencyObject
        {
            if (depObj == null) return null;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                var child = VisualTreeHelper.GetChild(depObj, i);

                var result = (child as T) ?? GetChildOfType<T>(child);
                if (result != null) return result;
            }
            return null;
        }
    }