使用TreeViewItem的自定义样式时,Wpf树视图双向绑定不起作用

时间:2018-03-26 06:50:31

标签: wpf treeview two-way-binding

我尝试设置一个自定义样式的树视图,它通过双向将展开的属性绑定到视图模型中的类似属性来“及时”加载。样式和功能方面可以自行完成,但不能放在一起。

当我这样做时,功能就在那里:

<TreeView Name="treeView" ItemsSource="{Binding}" Grid.Column="0">
    <TreeView.Resources>
        <ResourceDictionary  Source="GroupedTreeViewItemStyle.xaml"/>
    </TreeView.Resources>

    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded"  Value="{Binding Expanded, Mode=TwoWay}"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

但是当我添加BasedOn以使用我的自定义样式时,它不再加载任何节点。 我通过用以下内容替换上面的样式定义来使用我的样式:

<Style TargetType="TreeViewItem" BasedOn="{StaticResource GroupedTreeViewItemStyle}">

这是我基于this教程的自定义样式:

<ResourceDictionary  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:this="*******namespace omitted*******">

<!-- This Style redefines the ControlTemplate used by TreeViewItems and
   also provides a different itemspanel for their child items. -->
<Style TargetType="TreeViewItem" x:Key="GroupedTreeViewItemStyle">
    <Style.Resources>
        <LinearGradientBrush x:Key="ItemAreaBrush" StartPoint="0.5, 0" EndPoint="0.5, 1" Opacity="1">
            <GradientStop Color="#fff" Offset="0" />
            <GradientStop Color="#f2fcfe" Offset="1" />
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="SelectedItemAreaBrush" StartPoint="0.5, 0" EndPoint="0.5, 1" Opacity="1">
            <GradientStop Color="#fff" Offset="0" />
            <GradientStop Color="#f2fcfe" Offset="1" />
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="ItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
            <GradientStop Color="#243B55" Offset="0" />
            <GradientStop Color="#141E30" Offset="1" />
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="SelectedItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
            <GradientStop Color="#243B55" Offset="0" />
            <GradientStop Color="#141E30" Offset="1" />
        </LinearGradientBrush>

        <DropShadowBitmapEffect x:Key="DropShadowEffect" />
    </Style.Resources>



    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TreeViewItem">
                <Grid Margin="8,4">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>

                    <!-- This Border contains elements which display 
             the content and child items of the TreeViewItem. -->
                    <Border Name="Bd" 
          Background="{StaticResource ItemAreaBrush}"
          BorderBrush="{StaticResource ItemBorderBrush}" 
          BorderThickness="0.6" 
          CornerRadius="8"              
          Padding="6"     
          SnapsToDevicePixels="True"
          >
                        <Grid>
                            <!-- Items with children are 
                 shown in an Expander. -->
                            <Expander Name="Exp" IsExpanded="{TemplateBinding TreeViewItem.IsExpanded}">
                                <Expander.Header>
                                    <!-- Displays the item's header in the Expander. -->
                                    <ContentPresenter ContentSource="Header" />
                                </Expander.Header>
                                <!-- Displays the item's children. -->
                                <ItemsPresenter />
                            </Expander>

                            <!-- Items without children are 
                 shown in a ContentPresenter. -->
                            <ContentPresenter Name="CntPres"
              ContentSource="Header"
              HorizontalAlignment="Center"
              VerticalAlignment="Center"
              Visibility="Collapsed" 
              />
                        </Grid>
                    </Border>
                </Grid>

                <ControlTemplate.Triggers>
                    <!-- If the TreeViewItem has child items,
             show it in an Expander.  Otherwise
             hide the Expander and show the hidden
             ContentPresenter. -->
                    <Trigger Property="TreeViewItem.HasItems" Value="false">
                        <Setter 
            TargetName="Exp" 
            Property="Visibility" 
            Value="Collapsed" />
                        <Setter 
            TargetName="CntPres" 
            Property="Visibility" 
            Value="Visible" />
                    </Trigger>

                    <!--When the item is selected in the TreeView, use the 
            "selected" colors and give it a drop shadow. -->
                    <Trigger Property="IsSelected" Value="true">
                        <Setter
            TargetName="Bd"
            Property="Panel.Background"                     
            Value="{StaticResource SelectedItemAreaBrush}" />
                        <Setter
            TargetName="Bd"
            Property="Border.BorderBrush"                     
            Value="{StaticResource SelectedItemBorderBrush}" />
                        <!--<Setter
            TargetName="Bd"
            Property="TextElement.Foreground"                   
            Value="{DynamicResource 
              {x:Static SystemColors.HighlightTextBrushKey}}" />-->
                        <Setter
            TargetName="Bd"
            Property="Border.BitmapEffect"                  
            Value="{StaticResource DropShadowEffect}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <!-- Make each TreeViewItem show it's children 
     in a StackPanel. If it is a root item then
     the Orientation will be 'Horizontal', else
     'Vertical'. -->
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <ItemsPanelTemplate.Resources>
                    <this:ItemsPanelOrientationConverter x:Key="conv" />
                </ItemsPanelTemplate.Resources>
                <StackPanel 
        IsItemsHost="True" 
        Orientation="{Binding 
          RelativeSource={x:Static RelativeSource.TemplatedParent}, 
          Converter={StaticResource conv}}" 
        />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>


</Style>

有人知道,在结合树的风格和功能方面我做错了什么? 问题是样式是否已根据isExpanded属性定义了某些内容?或者是否有某些东西缺失,类似于super(isExpanded)

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

扩展器绑定可能是问题的原因:

<Expander Name="Exp" IsExpanded="{TemplateBinding TreeViewItem.IsExpanded}">

根据documentation

  

模板绑​​定始终是单向绑定,即使涉及的属性默认为双向绑定。

(另见TemplateBinding limitations

尝试重新编写绑定:

<Expander Name="Exp" 
          IsExpanded="{Binding IsExpanded, 
                               RelativeSource={RelativeSource TemplatedParent}}">