2

I've bind ObservableCollection of Layer to a TreeView in WPF .

Layer definition is :

public class Layer 
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Color { get; set; }
    public GeoType Type { get; set; }
}

public enum GeoType { Area, Line, Point }

This is TreeView XAML :

<TreeView  Grid.Column="0"
          ItemsSource="{Binding Layers}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding SubLayers}">
            <StackPanel Orientation="Horizontal">

                <Canvas Background="LightGray">
                    <Ellipse Fill="{Binding Color}"
                             Height="15"
                             Width="15"
                             StrokeThickness="5"
                             Stroke="{Binding Color}"/>
                </Canvas>

                <TextBlock Margin="20,0,0,0" Text="{Binding Path=Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

I want to specify shape type based on GeoType property. I mean if GeoType is Line instead of canvas in above XAML it should be Line. How can I do it using binding? Should I create converter?

4

1 回答 1

1

You can do it using the with pure XAML.

...
<Window.Resources>
    <DataTemplate x:Key="LineTemplate">
        <Line />
    </DataTemplate>
    <DataTemplate x:Key="EllipseTemplate">
        <Ellipse />
    </DataTemplate>
    ... etc
</Window.Resources>
...

<TreeView  Grid.Column="0"
          ItemsSource="{Binding Layers}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding SubLayers}">
            <StackPanel Orientation="Horizontal">
                <Canvas Background="LightGray">
                    <ContentControl Content="{Binding}">
                        <ContentControl.Style>
                            <Style TargetType="ContentControl">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=Type}" Value="{StaticResource local:GeoType.Line}">
                                        <Setter Property="ContentTemplate" Value="{StaticResource LineTemplate}" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Path=Type}" Value="{StaticResource local:GeoType.Ellipse}">
                                        <Setter Property="ContentTemplate" Value="{StaticResource EllipseTemplate}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ContentControl.Style>
                    </ContentControl>
                </Canvas>

                <TextBlock Margin="20,0,0,0" Text="{Binding Path=Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

It is only one of many possible solutuion. local is the namespace where your GeoType is. You should decorate the templates inside the resources to use data binding.

于 2012-12-15T07:56:02.157 回答