使用具有相同(但克隆)的itemssource的多个Treeview对象

时间:2013-11-01 19:52:25

标签: wpf listview binding treeview

所以,我有一个listviewdatatemplates不同,如下所示:

<ListView Panel.ZIndex="0" x:Name="FilterList" Margin="10,0" Grid.Row="2" 
    Grid.ColumnSpan="3" Background="White" ItemTemplateSelector="{StaticResource 
    ReportFilterTemplateSelector}" ItemsSource="{Binding reportParameters, 
    Mode=TwoWay}" ScrollViewer.CanContentScroll="False">

我可以在下面看到我的一个示例datatemplates。一切都很棒。我的问题是,对于这个(和其他)datatemplates,我可以有多个同一个实例。在此特定情况下,treeview itemssource绑定到DataContext.OfficeListText以填充所有元素。

    <DataTemplate x:Key="office">
        <Grid MinHeight="35" MaxHeight="250">
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding rpName}" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" />
            <Expander HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" 
                Header="{Binding Path=DataContext.OfficeListText, RelativeSource=
                {RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" 
                VerticalAlignment="Top" ExpandDirection="Down">

                <TreeView Tag="{Binding rpParameter}" HorizontalAlignment="Stretch" 
                    VerticalAlignment="Stretch" ItemsSource="{Binding 
                    Path=DataContext.OfficeList, RelativeSource={RelativeSource 
                    FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay}" 
                    ItemTemplate="{StaticResource CheckBoxItemTemplate}" 
                    ItemContainerStyle="{StaticResource TreeViewItemStyle}"/>
            </Expander>
        </Grid>
    </DataTemplate>

这方面的主要问题是,例如,如果我选择第一个treeview中的办公室,则第二个treeview显示相同的问题。基本上我希望他们最初拥有相同的itemssource但具有单独的实例。因为它们是动态生成的,所以我会陷入困境。任何帮助,将不胜感激。

我不确定其他代码是否必要,因为我确信大部分代码都是基于我需要做的工作来做出不妥之处,但是如果你想要更多,我会很乐意提供。谢谢!

1 个答案:

答案 0 :(得分:0)

目前,您的TreeView绑定到属于UserControl的DataContext的OfficeList的单个实例。这意味着每个TreeView都指向同一个列表。如果我正确理解您的问题,您真正想要的是为每个TreeView创建一个不同的OfficeList实例。

每次将DataTemplate应用于reportParameter时,我都不建议实例化新的OfficeList。你可以用ValueConverter做到这一点,但它会很糟糕。

更干净的解决方案是拥有一个包含reportParameter数据的类,以及一个OfficeList实例,然后绑定到该类的实例,而不是绑定到UserControl。根据reportParameters的结构(我假设reportParameters是ReportParameter类型的对象列表),有两种方法可以执行此操作:

1)如果ReportParameter是ViewModel,您只需将OfficeList属性添加到R​​eportParameter类,并在实例化每个ReportParameter时对其进行初始化。

然后你的TreeView看起来像这样:

<TreeView Tag="{Binding rpParameter}" HorizontalAlignment="Stretch" 
    VerticalAlignment="Stretch" ItemsSource="{Binding Path=OfficeList, Mode=TwoWay}" 
    ItemTemplate="{StaticResource CheckBoxItemTemplate}" 
    ItemContainerStyle="{StaticResource TreeViewItemStyle}"/>

2)如果ReportParameter不是ViewModel(因此不适合添加OfficeList参数),那么创建一个名为ReportParameterViewModel的新类,它包含2个属性:ReportParameter和OfficeList。而不是将ListView绑定到ReportParameter列表,而是绑定到ReportParameterViewModel列表。

然后你的ListView看起来像这样:

<ListView Panel.ZIndex="0" x:Name="FilterList" Margin="10,0" Grid.Row="2" 
    Grid.ColumnSpan="3" Background="White" ItemTemplateSelector="{StaticResource 
    ReportFilterTemplateSelector}" ItemsSource="{Binding reportParameterViewModels, 
    Mode=TwoWay}" ScrollViewer.CanContentScroll="False">

您的TextBlock将如下所示:

<TextBlock Text="{Binding ReportParameter.rpName}" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" />

您的TreeView将如下所示:

<TreeView Tag="{Binding rpParameter}" HorizontalAlignment="Stretch" 
    VerticalAlignment="Stretch" ItemsSource="{Binding Path=OfficeList, Mode=TwoWay}" 
    ItemTemplate="{StaticResource CheckBoxItemTemplate}" 
    ItemContainerStyle="{StaticResource TreeViewItemStyle}"/>