整个行上的WPF树视图项背景

时间:2013-04-05 05:34:28

标签: c# wpf treeview wpf-controls treeviewitem

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

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

现在我有文本块的背景,但它看起来很可怕,我想要整个行的背景(我认为它看起来会好很多)。

现在看来是这样的:
img1

但我需要的是:
img2

如果我更改边框背景的值,我会更改所有项目(逻辑上)。所以我想我真的需要处理文本块背景,但是我不能在整行上扩展(拉伸不是解决方案,因为它只是将它扩展到行的末尾而不是之前的那个空格)。

感谢您的建议。

编辑: 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>

3 个答案:

答案 0 :(得分:3)

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

preview

            <TreeView Grid.Row="1"  Name="treeView" Margin="5">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                    <Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                    <!-- Style for the selected item -->
                    <Setter Property="BorderThickness" Value="1"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TreeViewItem}">
                                <ControlTemplate.Resources>
                                    <Conv: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="0" 
                                                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 TargetName="Bd" Property="Background" Value="#FFF7D280"/>
                                        <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 TargetName="Bd" Property="Background" Value="#FFDADADA"/>
                                        <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.Triggers>
                        <!-- Selected and has focus -->
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="BorderBrush" Value="{StaticResource HT_Background_Orange}"/>
                        </Trigger>
                        <!-- Mouse over -->
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#FFFDE8BA"/>
                            <!--<Setter Property="Background">
                                <Setter.Value>
                                    <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                                        <GradientStop Color="#FFFAFBFD" Offset="0"/>
                                        <GradientStop Color="#fadfa3" Offset="1"/>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>-->
                            <Setter Property="BorderBrush" Value="#f59246"/>
                        </Trigger>
                        <!-- Selected but does not have the focus -->
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="True"/>
                                <Condition Property="IsSelectionActive" Value="False"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="BorderBrush" Value="#f59246"/>
                        </MultiTrigger>
                    </Style.Triggers>
                    <Style.Resources>
                        <Style TargetType="Border">
                            <Setter Property="CornerRadius" Value="0"/>
                        </Style>
                    </Style.Resources>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:FileSystemObjectInfo}" ItemsSource="{Binding Path=Children}">
                    <StackPanel Orientation="Horizontal">
                        <Image
                            Source="{Binding Path=ImageSource, UpdateSourceTrigger=PropertyChanged}" 
                            Margin="0,1,8,1"
                            Height="24"
                            Width="24"/>
                        <TextBlock
                            Text="{Binding Path=FileSystemInfo.Name}"
                            VerticalAlignment="Center"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
            <TreeView.Resources>

                <!-- Brushes for the selected item -->
                <LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" EndPoint="0,1" StartPoint="0,0">
                    <GradientStop Color="#FFFDF2DA" Offset="0"/>
                    <GradientStop Color="#FFF7D280" Offset="1"/>
                </LinearGradientBrush>
                <LinearGradientBrush x:Key="{x:Static SystemColors.ControlBrushKey}" EndPoint="0,1" StartPoint="0,0">
                    <GradientStop Color="White" Offset="0"/>
                    <GradientStop Color="#FFE2E2E2" Offset="1"/>
                </LinearGradientBrush>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="Black" />
            </TreeView.Resources>
        </TreeView>

如果您有任何疑问,请与我们联系!

此致

答案 1 :(得分:0)

使用How to get children of a WPF container by type?中的GetChildOfType方法来完成Dominic Jonas的解决方案:

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

然后仅在一行上突出显示鼠标:How can I make WPF Trigger for IsMouseOver on TreeViewItem NOT affect all parents of the moused-over control?

答案 2 :(得分:-1)

使用snoop了解您尝试修改的可视树。这样,实际知道您需要修改的内容需要2-3分钟。 (谷歌)

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

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

如果你想要背景颜色,你还需要添加触发器。

相关问题