显示分层结构 - 缺少/无效的datacontext

时间:2013-03-30 17:13:00

标签: c# wpf xaml datacontext hierarchicaldatatemplate

我正在尝试显示这种层次结构:

public interface IProgressIndicator
{
    CancellationToken CancellationToken { get; }
    string Name { get; set; }
}

public interface IPercentageProgressIndicator : IProgressIndicator
{
    int ProgressPercentage { get; set; }
}

public interface ICountProgressIndicator : IProgressIndicator
{
    int ProgressPercentage { get; }
    int CurValue { get; set; }
    int MaxValue { get; set; }
}

public interface ICompositeProgressIndicator : ICountProgressIndicator
{
    ObservableCollection<IProgressIndicator> SubProgressItems { get; }

    void MarkAsComplete(IProgressIndicator progress);

    IPercentageProgressIndicator CreatePercentageIndicator();
    ICountProgressIndicator CreateCountIndicator();
    ICompositeProgressIndicator CreateCompositeIndicator();
}

视图不应假设层次结构已到位;即应显示常规IProgressIndicator(使用ContentControl)并使用DataTemplates显示其他类型。

因此,当IProgressIndicator是ICompositeProgressIndicator时,整个层次结构的根应该是TreeView,根树视图项显示信息(如ProgressPercentage和Name)。然后,子项应再次显示为IProgressIndicator并使用DataTemplates选择适当的方式来查看其数据。嵌套的ICompositeProgressIndicator对象应该只添加另一个树视图项(不是整个TreeView)。

这就是我想出的。我不得不使用Complex Hierarchical Data Templates。我也使用自定义DataTemplateSelector,这非常简单:

public class ProgressIndicatorTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var element = (container as FrameworkElement);

        if (item is ICompositeProgressIndicator)
            return element.FindResource("CompositeProgressIndicatorTemplate") as DataTemplate;
        else if (item is ICountProgressIndicator)
            return element.FindResource("CountProgressIndicatorTemplate") as DataTemplate;
        else if (item is IPercentageProgressIndicator)
            return element.FindResource("PercentageProgressIndicatorTemplate") as DataTemplate;
        return null;
    }
}

这是XAML:

<StackPanel Grid.Row="2" Margin="5" Orientation="Vertical">
    <StackPanel.Resources>
        <editorUtil:ProgressIndicatorTemplateSelector x:Key="progressIndicatorTemplateSelector" />
        <Converters:ObjectToTypeConverter x:Key="objectTypeConverter" />

        <DataTemplate x:Key="CompositeProgressIndicatorTemplateBase">
            <StackPanel Orientation="Vertical">
                <TextBlock Text="CompositeProgressIndicatorTemplateBase" />
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding SubProgressItems.Count}" />
                <TextBlock Text="{Binding Converter={StaticResource objectTypeConverter}}"  Margin="5" />
            </StackPanel>
        </DataTemplate>

        <DataTemplate x:Key="CompositeProgressIndicatorTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="0" Orientation="Vertical">
                    <TextBlock Text="CompositeProgressIndicatorTemplateBase" />
                    <TextBlock Text="{Binding Name}" />
                    <TextBlock Text="{Binding SubProgressItems.Count}" />
                    <TextBlock Text="{Binding Converter={StaticResource objectTypeConverter}}"  Margin="5" />
                </StackPanel>
                <TreeView Grid.Row="1" DataContext="{Binding}">
                    <TreeView.ItemContainerStyle>
                        <Style TargetType="{x:Type TreeViewItem}">
                            <Setter Property="IsExpanded" Value="true"/>
                        </Style>
                    </TreeView.ItemContainerStyle>
                    <TreeViewItem ItemsSource="{Binding SubProgressItems}" DataContext="{Binding}"
                          ItemTemplateSelector="{StaticResource progressIndicatorTemplateSelector}" IsExpanded="True">
                        <TreeViewItem.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <StackPanel.DataContext>
                                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type coreUtil:ICompositeProgressIndicator}}"
                                                 Path="."/>
                                    </StackPanel.DataContext>
                                    <TextBlock Text="CompositeProgressIndicatorTemplate" />
                                    <ContentControl ContentTemplate="{StaticResource CompositeProgressIndicatorTemplateBase}">
                                        <ContentControl.DataContext>
                                            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type coreUtil:ICompositeProgressIndicator}}"
                                                 Path="."/>
                                        </ContentControl.DataContext>
                                    </ContentControl>
                                </StackPanel>
                            </DataTemplate>
                        </TreeViewItem.HeaderTemplate>
                    </TreeViewItem>
                </TreeView>
            </Grid>
        </DataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type coreUtil:ICompositeProgressIndicator}" ItemsSource="{Binding Path=SubProgressItems}">
            <ContentControl ContentTemplate="{StaticResource CompositeProgressIndicatorTemplateBase}" />
        </HierarchicalDataTemplate>
        <DataTemplate x:Key="CountProgressIndicatorTemplate" DataType="{x:Type coreUtil:ICountProgressIndicator}">
            <Grid>
                <ProgressBar Height="20" Value="{Binding ProgressPercentage, Mode=OneWay}" />
                <TextBlock Margin="5" HorizontalAlignment="Center" Text="{Binding ProgressPercentage, Converter={StaticResource percentageConverter}, StringFormat=P}" />
            </Grid>
        </DataTemplate>
        <DataTemplate x:Key="PercentageProgressIndicatorTemplate" DataType="{x:Type coreUtil:IPercentageProgressIndicator}">
            <Grid>
                <ProgressBar Height="20" Value="{Binding ProgressPercentage, Mode=OneWay}" />
                <TextBlock Margin="5" HorizontalAlignment="Center" Text="{Binding ProgressPercentage, Converter={StaticResource percentageConverter}, StringFormat=P}" />
            </Grid>
        </DataTemplate>
    </StackPanel.Resources>
    <ContentControl Content="{Binding ProgressIndicator}" ContentTemplateSelector="{StaticResource progressIndicatorTemplateSelector}">
    </ContentControl>
</StackPanel>

以下是目前的情况:

current visualization of XAML

根树视图项缺少DataContext。

0 个答案:

没有答案
相关问题