网格为DataTemplate,列数未知

时间:2017-10-30 17:13:12

标签: c# .net xaml grid datatemplate

我使用XAML开发我的应用程序UI,在后台运行C#程序。

让它更容易解释:让我们说程序应该在ListView / Grid中显示Paramters。

  1. 第1列是参数名称(字符串)
  2. 第2列是参数值(字符串或字符串[,])
  3. 参数值可以是单个值(显示为标签)或矢量/矩阵(在此单元格内显示为网格)。我不知道如何在这里添加一个未知列号的其他网格,每个参数的数量都不同。

    所有参数都在List中,并动态加载ItemSource + DisplayMemberBinding。

    所以我需要的是: - DataTemplate中的网格 - 行数未知的网格

    <DataTemplate x:Key="labelTemplate">
      <Label Content="{Binding Path=Value}" Width="Auto"></Label>
    </DataTemplate>
    
    <DataTemplate x:Key="table2DTemplate">
    </DataTemplate>
    
    <local:ParameterTemplateSelector 
      x:Key="parameterTemplateSelector" 
      LabelTemplate="{StaticResource labelTemplate}" 
      Table2DTemplate ="{StaticResource table2DTemplate}"/>
    

    MY Datatempaltes + TemplateSelector:

    <ListView ItemsSource="{Binding Parameters}" Margin="10,156,10.286,10.429" x:Name="listBox1" FontSize="8" Background="White" Foreground="Black" BorderBrush="#FF60EFBB">
      <ListView.View>
        <GridView>
                <GridViewColumn 
                    Header="Name" 
                    Width="Auto"
                    DisplayMemberBinding="{Binding Name}" />
                <GridViewColumn 
                    Header="Value" 
                    Width="Auto"
                    CellTemplateSelector="{StaticResource parameterTemplateSelector}" />
                <GridViewColumn 
                    Header="Unit" 
                    Width="Auto"
        </GridView>
      </ListView.View>
    </ListView>
    

1 个答案:

答案 0 :(得分:0)

这是你想做的事。值转换器是必需的,因为您不能将ItemsControl(或其任何子类,如ListBox,ListView等)绑定到二维数组。因此,我们将2D数组转换为List<List<String>>并在嵌套的ItemsControls中显示。转换器包含在下面。

如果您愿意在代码中使用List<List<String>>代替string[,],则可以简化此操作,但这可能不切实际。

<DataTemplate x:Key="table2DTemplate">
    <ItemsControl 
        ItemsSource="{Binding Value, Converter={StaticResource ListOfListsFrom2DArray}}"
        >
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Label Content="{Binding}" />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid
                                Rows="1"
                                />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</DataTemplate>

转换器。除了LINQ表达式stole from another StackOverflow answer之外,这里并不多见。

public class ListOfListsFrom2DArray : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var values = value as string[,];

        //  https://stackoverflow.com/a/37458182/424129
        var result = values.Cast<string>()
            // Use overloaded 'Select' and calculate row index.
            .Select((x, i) => new { x, index = i / values.GetLength(1) })
            // Group on Row index
            .GroupBy(x => x.index)
            // Create List for each group.  
            .Select(x => x.Select(s => s.x).ToList())
            .ToList();

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}