C# 在WPF中显示多维数据

C# 在WPF中显示多维数据,c#,wpf,data-binding,visual-studio-2010,multidimensional-array,C#,Wpf,Data Binding,Visual Studio 2010,Multidimensional Array,在WPF中显示多维数据的最佳方式是什么?直到运行时,我才知道数据的大小/形状。理想情况下,我希望使用数据绑定,但这不是一个严格的要求。我在考虑某种网格,但我不知道如何动态绑定到数据并让它计算出行数和列数。请给出建议和示例?我做过类似的事情,数据是一个或多个列表,或数组。不确定对“类似网格”的数据使用多维数组与使用这种方法相比有多困难 下面是我如何与列表列表绑定的 <Resources> <DataTemplate x:Key="GridDtInn

在WPF中显示多维数据的最佳方式是什么?直到运行时,我才知道数据的大小/形状。理想情况下,我希望使用数据绑定,但这不是一个严格的要求。我在考虑某种网格,但我不知道如何动态绑定到数据并让它计算出行数和列数。请给出建议和示例?

我做过类似的事情,数据是一个或多个列表,或数组。不确定对“类似网格”的数据使用多维数组与使用这种方法相比有多困难

下面是我如何与列表列表绑定的

        <Resources>
        <DataTemplate x:Key="GridDtInner">
            <TextBlock Text="{Binding YourProperty}"/>
        </DataTemplate>
        <DataTemplate x:Key="GridDtOuter">
            <ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource GridDtInner}" />
        </DataTemplate>     
        </Resources> 
        <ItemsControl  ItemTemplate="{DynamicResource GridDtOuter}" ItemsSource="{Binding YourList, Mode=Default}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
        </ItemsControl>

显然,为了简洁,我删掉了一些东西,但我希望这是有意义的

问候,


迈克·麦考莱(Mike McAulay)

我做过一些非常相似的事情,但很可能是在一个与你工作的行业完全不同的行业

当你说数据的大小/形状时,我假设你不是在说圆和正方形,而是说你有一个NxM数据矩阵,直到运行时你才知道N和M是什么。我还假设您希望在NxM矩阵的每个单元格中显示某种文本

请注意,下面的XAML是根据我的代码修改的,没有经过测试,但我想让您了解一下我是如何做到这一点的

        <ListBox Width="300" Height="300" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding Cells}">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Width="Auto" Height="Auto" ItemWidth="{Binding CellBoundary}" ItemHeight="{Binding CellBoundary}"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Width="{Binding CellDiameter}" Height="{Binding CellDiameter}" Text="{Binding CellValue}"></TextBlock>
                </DataTemplate>                    
            </ListBox.ItemTemplate>
        </ListBox>

我将列表框的ItemsPanel更改为一个列表框。所以只要你有一个NxM矩阵(它也可以是稀疏的),你就可以把它当作一个带有NxM单元的向量。每个单元格实际上都是列表框中的一个项目

接下来,将每个ListBox项的DataTemplate设置为一个TextBlock,其中TextBlock的大小是数据绑定的,显示的值位于单元格的
CellValue
成员中,该成员是一个
ObservableCollection
或类似的数据绑定到
单元格中

在代码隐藏中,此时唯一需要做的事情是计算出N和M是什么,并进行必要的数学运算来计算列表框的大小(可以在ViewBox内部以使其缩放),以便相应地显示值。显然,您还需要将我的硬编码值更改为数据绑定的值

这种方法对我来说似乎是最简单的,所以我一直在用它来处理我的东西


我还应该补充一点,为了制作稀疏矩阵,您将CellValue设置为0,但如果值为0,您也可以使用DataTrigger使文本块不可见,从而产生稀疏矩阵的错觉。

我认为最好的解决方案是只使用TreeView:)如果您使用MVVM,这是我发现的关于TreeView的最精彩的教程:


如果您需要更多信息,请随时通知我。

我刚刚在WPF工具包中找到了DataGrid,它显示了一些潜力。它至少允许选择单个单元格。当我弄清楚数据绑定时,我会发布代码


听起来好像您希望为具有编辑功能的二维阵列提供类似Excel的界面。对于其他维度,您必须使用选项卡或一系列组合框

查看WPF工具包DataGrid。有一个自动生成列的选项。尝试一下

但是,由于Datagrid只能表示二维数据,因此您将需要一些代码来处理其他维度

科里

编辑:(2010年4月28日)以下是一个可行的解决方案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using Microsoft.Windows.Controls;

namespace WpfApplication2
{
    public partial class MainWindow : Window
    {
    public List<List<object>> TheData { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        // Generate some random data
        Random r = new Random();

        TheData = new List<List<object>>
        {
            new List<object> { r.Next(100), r.Next(100), r.Next(100),r.Next(100) },
            new List<object> {  r.Next(100), r.Next(100), r.Next(100),r.Next(100) },
            new List<object> {  r.Next(100), r.Next(100), r.Next(100) },
            new List<object> {  r.Next(100), r.Next(100), r.Next(100),r.Next(100) },
            new List<object> {  r.Next(100), r.Next(100), r.Next(100),r.Next(100) },
            new List<object> {  r.Next(100), r.Next(100), r.Next(100),r.Next(100), r.Next(100) }
        };

        // Now bind data to the grid
        // We need at least one element
        if (TheData.Count > 0)
        {
            // Find the longest row so we create enough columns
            var max = TheData.Max(c => c.Count);

            for (var i = 0; i < max; i++)
            {
                TheGrid.Columns.Add(
                    new DataGridTextColumn
                    {
                        Header = string.Format("Column: {0:00}", i),
                        Binding = new Binding(string.Format("[{0}]", i))
                    }
                    );
            }
        }

        TheGrid.ItemsSource = TheData;
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Windows;
使用System.Windows.Data;
使用Microsoft.Windows.Control;
命名空间WpfApplication2
{
公共部分类主窗口:窗口
{
公共列表数据{get;set;}
公共主窗口()
{
初始化组件();
//生成一些随机数据
随机r=新随机();
数据=新列表
{
新列表{r.Next(100)、r.Next(100)、r.Next(100)、r.Next(100)},
新列表{r.Next(100)、r.Next(100)、r.Next(100)、r.Next(100)},
新名单{r.Next(100)、r.Next(100)、r.Next(100)},
新列表{r.Next(100)、r.Next(100)、r.Next(100)、r.Next(100)},
新列表{r.Next(100)、r.Next(100)、r.Next(100)、r.Next(100)},
新列表{r.Next(100)、r.Next(100)、r.Next(100)、r.Next(100)、r.Next(100)}
};
//现在将数据绑定到网格
//我们至少需要一个元素
如果(数据计数>0)
{
//找到最长的行,以便创建足够的列
var max=数据最大值(c=>c.Count);
对于(变量i=0;i
}

XAML

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
    Title="GridTest">
<Grid x:Name="LayoutGrid">
    <toolkit:DataGrid x:Name="TheGrid"
                      AutoGenerateColumns="False"
                      IsReadOnly="False"
                      CanUserAddRows="False"/>
</Grid>

关于这种方法,需要注意的是,如果允许编辑数据并允许交错数组,则需要在短行上新建一个新列表


至于>2D数据,您需要某种选项来选择另一个维度,因为datagrid只能表示2D数据。

TreeView对我来说不是一个好的解决方案。数组数据需要以类似表格的方式显示(如excel网格或其他形式)。在本例中,我有两种选择