ItemsControl(虚拟化足球驱动信息)

发布于 2024-12-08 23:45:19 字数 9062 浏览 0 评论 0原文

我正在尝试模拟 NFL 驱动图来可视化游戏中的一些驱动数据。我粗略地尝试模仿的一个例子可以在这里看到,由 nfl.com 提供。我正在尝试实现以下目标:

  • 显示比赛场地
  • 在比赛场地顶部绘制数据
  • 当我将鼠标悬停在某物上时,我想触发一个事件(例如 工具提示)

http://www.nfl.com/ gamecenter/2011100909/2011/REG5/jets@patriots#menu=drivechart

这里是我现在,首先是 xaml:

<StackPanel x:Name="myStackPanel" Orientation="Vertical">
  <StackPanel.Background>
    <ImageBrush ImageSource="{StaticResource PlayingField}" Stretch="Fill" />
  </StackPanel.Background>
  <ItemsControl Background="AliceBlue" Opacity="0.5" 
                ItemsSource="{Binding Path=DriveDetails}"           
                ItemTemplate="{StaticResource myDataTemplate}" 
                ItemsPanel="{StaticResource myItemsPanelTemplate}" />
</StackPanel>

结果是:

(抱歉,因为我是新手,所以无法添加屏幕截图!)

我会尽力描述我所看到的内容,我相信你们大多数人在阅读完 xaml 后都会明白这一点。 基本上我在背景中看到了一个足球场,在左上角 - 我的 ItemsControl 控件。StackPanel

是不言自明的,我现在在调整图像大小时会遇到问题一码并不代表一个像素,但我将把它留到另一天,我主要关心的是如何可视化数据。另外,驱动器可视化不应从左上角开始:D 因此,纯粹处理 ItemsControl 我只剩下这个:

(抱歉,因为我是新手,所以无法添加屏幕截图!)

我将再次尝试描述该图像。它是前面提到的 ItemsControl 控件的特写,没有背景(足球场)图像。

注意:ItemsControl 背景已设置为 AliceBlue,以便更容易看到,一旦我让这个工作正常。

ItemsSource 绑定到“Play”类的列表:

public class Play
{
  public int Quarter { get; set; }
  public int Result { get; set; }
  public PlayType TypeOfPlay { get; set; }
  public double WidthOfPlay { get; set; }
}

PlayType 是一个枚举:

public enum PlayType
{
  Run,
  Pass,
  Penalty,
  Punt,
  FieldGoal
}

列表获取一些数据...(示例数据,我知道第一个下来已经获得了哈哈)

List<Play> SamplePlays = new List<Play>()
{
  new Play { Quarter = 1, Result = 5, TypeOfPlay = PlayType.Penalty, WidthOfPlay = 30 },
  new Play { Quarter = 1, Result = 5, TypeOfPlay = PlayType.Run, WidthOfPlay = 30 },
  new Play { Quarter = 1, Result = 5, TypeOfPlay = PlayType.Pass, WidthOfPlay = 30 },
  new Play { Quarter = 1, Result = 40, TypeOfPlay = PlayType.Punt, WidthOfPlay = 240 }
};

...并且被传承借助传输参数类到 ViewModel…

ucHomeInstance = ucDriveChartInstance;
((ucDriveChart)ucHomeInstance).setViewModel(new ucDriveChartVM(new ucDriveChartTP() 
  { Plays = SamplePlays }));

… 在这里它被分配给 DriveDetails 属性

public class ucDriveChartVM : ViewModelBase
{
    public List<Play> DriveDetails { get; set; }

    public ucDriveChartVM(ucDriveChartTP transferParameter)
    {
        this.DriveDetails = transferParameter.Plays;
    }
}

这是 ItemsPanel 的 xaml:

<ItemsPanelTemplate x:Key="myItemsPanelTemplate">
  <StackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>

这是 ItemTemplate 的 xaml – 请注意,我绑定到 WidthOfPlay,因为一码是背景图形上大约有 6 个单位,一旦我整理好图形和调整大小,我将绑定到实际的 Result 属性:

<DataTemplate x:Key="myDataTemplate">
  <StackPanel Orientation="Horizontal" Width="{Binding WidthOfPlay}"
              SnapsToDevicePixels="True" Style="{StaticResource onMouseOver}">
    <Border Padding="0,5,0,5">
      <Grid>
        <StackPanel Style="{StaticResource onMouseOver}">
          <Rectangle Width="{Binding WidthOfPlay}" Height="10" 
                     Fill="{Binding TypeOfPlay,
                       Converter={StaticResource PlayTypeToColourConverter}}" />
        </StackPanel>
      </Grid>
    </Border>
  </StackPanel>
</DataTemplate>

我将 PlayType 枚举转换为 Brush,这就是为什么您可以使用示例数据查看显示的颜色。

<converter:PlayToColour x:Key="PlayTypeToColourConverter"
  ColourRun="Red" ColourPass="Blue" ColourPenalty="Yellow" ColourSpecial="Purple" />

所以所有这些都工作正常 - 但显然表现并不如预期 - 看上面的例子,一次发球由许多次比赛组成,这些比赛彼此相邻,但作为一次比赛可能会导致负码数,它们也被放置在彼此下方,并在最后一场比赛结束时抵消!

所以我想这是我的问题 - 如何以这样的形式表示数据,即驱动器的每次播放都位于该特定驱动器的前一次播放下方,但也从最后一个驱动器的末尾开始(以某种方式偏移? )

由于一场游戏由多个驱动器组成,我将在稍后阶段传递一个“驱动器”列表,其中包含驱动器起始位置和该驱动器的比赛列表(而不是简单的比赛列表)这个例子)。

这意味着整个内容也需要可滚动

我认为使用 ItemsControl 控件以及 ItemTemplate 和 DataTemplate 的做法是正确的,但我肯定可以使用一些专家建议来实现这一目标。

如果您已经读到这里,感谢您抽出时间 - GO PATS ;)

[编辑]

非常感谢 AngelWPF(虚拟化)和Rachel(一切!)我实际上设法让它工作,至少对于我提供 ItemsControl 的播放列表来说是这样。 雷切尔,你的博客很棒。 AttachedProperties 条目确实非常有用,感谢您分享您的知识!

在稍后的阶段,我希望能够添加一两个屏幕截图,以更好地演示我正在胡思乱想的内容;)

按照建议,我使用(以及其他属性)PlayIndex 修改了 Play 类,用于网格定位

public class Play
{
  public int PlayIndex { get; set; }
  public int Quarter { get; set; }
  public int Down { get; set; }
  public int YardsToGo { get; set; }
  public int Position { get; set; }
  public PlayType TypeOfPlay { get; set; }
  public PlayDetail DetailsOfPlay { get; set; }
  public PlayResult ResultOfPlay { get; set; }
  public int YardsOfPlay { get; set; }
  public double PlayLength { get; set; }
  public string Player1 { get; set; }
  public string Player2 { get; set; }
}

并使用PlayIndex、ItemContainerStyle 被添加到 ItemsControl

<ItemsControl.ItemContainerStyle>
  <Style>
    <Setter Property="Grid.Column" Value="{Binding PlayIndex}" />
    <Setter Property="Grid.Row" Value="{Binding PlayIndex}" />
  </Style>
</ItemsControl.ItemContainerStyle>

将 ItemsPanelTemplate 从 StackPanel 更改为 Grid 也对此有所帮助:) 现在,每个 Play 都以各自的颜色相邻显示以及彼此下方显示。将 ToolTip 添加到 ItemsControl(使用 Play 类中的其他属性)将其完善。

正如我已经说过的,现在对于播放项目列表(为简单起见而缩短)来说,这非常有效:

List<Play> SamplePlays = new List<Play>()
{
  new Play { PlayIndex = 0, Position = 30, YardsOfPlay = 5, PlayLength = 25 },
  new Play { PlayIndex = 1, Position = 35, YardsOfPlay = 15, PlayLength = 75 },
  new Play { PlayIndex = 2, Position = 50, YardsOfPlay = 0, PlayLength = 0 },
  new Play { PlayIndex = 3, Position = 50,  YardsOfPlay = 8, PlayLength = 40 },
  new Play { PlayIndex = 4, Position = 58,  YardsOfPlay = 1, PlayLength = 5 },
  new Play { PlayIndex = 5, Position = 59,  YardsOfPlay = 30, PlayLength = 150 }
};

但是我将如何绑定我在原始帖子末尾所写的关于传递“驱动器”列表的内容”?

请注意 - 我在原来的帖子中写了这个,我希望这“允许”我用更多信息编辑这篇帖子,而不是提出一个全新的问题!

给定以下“Drive”类:

public class Drive
{
  public int DriveIndex { get; set; }
  public int StartPos { get; set; }
  public int EndPos { get; set; }
  public double DriveLength { get; set; }
  public DriveResult Result { get; set; }
  public List<Play> DrivePlays { get; set; }
}

用数据填充列表(使用与上面相同的操作)

List<Drive> SampleDrives = new List<Drive>() 
{
  new Drive { DriveIndex = 0, StartPos = 30, EndPos = 49, DriveLength = 19,
              DrivePlays = new List<Play>() 
              {
                // create plays here
              }},
  new Drive { DriveIndex = 1, StartPos = 30, EndPos = 49, DriveLength = 19,
              DrivePlays = new List<Play>() 
              {
                // create plays here
              }}
};

,ViewModel 现在看起来像这样:

public class ucDriveChartVM : ViewModelBase
{
  public List<Play> DriveDetails { get; set; }
  public List<Drive> Drives { get; set; }

  public ucDriveChartVM(ucDriveChartTP transferParameter)
  {
    this.DriveDetails = transferParameter.Plays;
    this.Drives = transferParameter.Drives;
  }
}

我显然需要使用另一个 DataTemplate 提供此 ItemsControl(包含驱动器),但此 DataTemplate 将具有将播放保存在该驱动器列表中。我很快发现你不能将内容放在矩形中,所以我必须仔细考虑一下:/

经过一些实验,我绑定到 DriveLength 属性以图形方式查看给定驱动器的长度并出现使用 DataGridCell,以便我可以在其中放置内容(例如 StackPanel)。

(我知道除了驱动器的长度之外,我没有绑定任何东西,这个例子中的矩形只是为了在测试时显示一些东西!)

<DataTemplate x:Key="myDataTemplateDrives">
  <StackPanel Orientation="Horizontal" Width="{Binding DriveLength}" 
              SnapsToDevicePixels="True" Margin="0,0,1,0">
    <Border>
      <Grid>
        <StackPanel>
          <DataGridCell>
            <StackPanel Width="{Binding Path=DriveLength}">
              <Rectangle Height="10" Fill="Gray" />
            </StackPanel>
          </DataGridCell>
        </StackPanel>
      </Grid>
    </Border>
  </StackPanel>
</DataTemplate>

但是我已经喝完了第四杯咖啡,我遇到了麻烦绑定到 List 对象内的 List?像 Drives.DrivePlays 这样的东西?!

所以我将从一个简单的(谢谢你们俩)

List<Play>

绑定转到一个

List<Drive>

的绑定

List<Play>!

包含名为“DrivePlays”

:D我是否遗漏了一些明显的东西,或者我需要更多咖啡吗?

编辑

我已经在一个单独的问题中解释了问题的最后一部分

相关问题关于原始问题的最后部分

I’m trying to emulate an NFL drive chart to visualize some drive data from a game. An example of what I’m roughly trying to emulate can be seen here, courtesy of nfl.com. I’m trying to achieve the following:

  • Display the playing field
  • Draw the data on top of the playing field
  • When I mouse-over something, then I want to fire off an event (e.g.
    ToolTip)

http://www.nfl.com/gamecenter/2011100909/2011/REG5/jets@patriots#menu=drivechart

Here is where I’m at right now, first of all the xaml:

<StackPanel x:Name="myStackPanel" Orientation="Vertical">
  <StackPanel.Background>
    <ImageBrush ImageSource="{StaticResource PlayingField}" Stretch="Fill" />
  </StackPanel.Background>
  <ItemsControl Background="AliceBlue" Opacity="0.5" 
                ItemsSource="{Binding Path=DriveDetails}"           
                ItemTemplate="{StaticResource myDataTemplate}" 
                ItemsPanel="{StaticResource myItemsPanelTemplate}" />
</StackPanel>

The result of which being:

(Sorry, as I'm a newbie I can't add the screenshot!)

I will do my best to describe what I'm seeing, I'm sure most of you will have this figured out after reading the xaml.
Basically I see a football playing field in the background and, in the top left corner - my ItemsControl control.

The StackPanel is self-explanatory, I now that I’m going to have problems later with the image with resizing as one yard does not represent one pixel but I’ll be leaving that for another day, my main concern is how I can visualize the data. Also, the drive visualization should not start in the top left corner :D So dealing purely with the ItemsControl I’m left with this:

(Sorry, as I'm a newbie I can't add the screenshot!)

Once again, I will attempt to describe the image. It is a closeup of the aforementioned ItemsControl control, with no background (football playing field) image.

Note: The ItemsControl Background has been set to AliceBlue so that it’s easier to see, it will be Transparent once I have this working.

The ItemsSource is bound to a list of the “Play” class:

public class Play
{
  public int Quarter { get; set; }
  public int Result { get; set; }
  public PlayType TypeOfPlay { get; set; }
  public double WidthOfPlay { get; set; }
}

PlayType is an enum:

public enum PlayType
{
  Run,
  Pass,
  Penalty,
  Punt,
  FieldGoal
}

The list gets some data… (sample data, I know that a 1st down has been gotten lol)

List<Play> SamplePlays = new List<Play>()
{
  new Play { Quarter = 1, Result = 5, TypeOfPlay = PlayType.Penalty, WidthOfPlay = 30 },
  new Play { Quarter = 1, Result = 5, TypeOfPlay = PlayType.Run, WidthOfPlay = 30 },
  new Play { Quarter = 1, Result = 5, TypeOfPlay = PlayType.Pass, WidthOfPlay = 30 },
  new Play { Quarter = 1, Result = 40, TypeOfPlay = PlayType.Punt, WidthOfPlay = 240 }
};

… and is passed on with the help of a transfer parameter class to the ViewModel…

ucHomeInstance = ucDriveChartInstance;
((ucDriveChart)ucHomeInstance).setViewModel(new ucDriveChartVM(new ucDriveChartTP() 
  { Plays = SamplePlays }));

… where it is assigned to the DriveDetails property

public class ucDriveChartVM : ViewModelBase
{
    public List<Play> DriveDetails { get; set; }

    public ucDriveChartVM(ucDriveChartTP transferParameter)
    {
        this.DriveDetails = transferParameter.Plays;
    }
}

Here is the xaml for the ItemsPanel:

<ItemsPanelTemplate x:Key="myItemsPanelTemplate">
  <StackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>

Here is the xaml for the ItemTemplate – please note that I’m binding to WidthOfPlay as one yard is roughly 6 units on the background graphic, once I get the graphic and resizing sorted out, then I’ll bind to the actual Result property:

<DataTemplate x:Key="myDataTemplate">
  <StackPanel Orientation="Horizontal" Width="{Binding WidthOfPlay}"
              SnapsToDevicePixels="True" Style="{StaticResource onMouseOver}">
    <Border Padding="0,5,0,5">
      <Grid>
        <StackPanel Style="{StaticResource onMouseOver}">
          <Rectangle Width="{Binding WidthOfPlay}" Height="10" 
                     Fill="{Binding TypeOfPlay,
                       Converter={StaticResource PlayTypeToColourConverter}}" />
        </StackPanel>
      </Grid>
    </Border>
  </StackPanel>
</DataTemplate>

I’m converting the PlayType enum into a Brush which is why with the sample data you can see the colours that are displayed.

<converter:PlayToColour x:Key="PlayTypeToColourConverter"
  ColourRun="Red" ColourPass="Blue" ColourPenalty="Yellow" ColourSpecial="Purple" />

So all of that is working ok – but obviously the representation is not as wished - looking at the example at the top, a drive consists of numerous plays, which are placed next to each other, but as a play can result in negative yardage, they are also placed underneath each other, offset by the end of the last play!

So I guess this is my question - how can I represent the data in such a form, that each play of a drive is positioned underneath the previous play of that particuler drive, but also starting at the end of that last drive (offset somehow?)

As a game consists of more than one drive I will, at a later stage, be passing on a list of “Drives” consisting of the drive starting position and a list of plays for that drive (instead of the simple list of plays in this example).

This means that the whole thing needs to be scrollable as well!

I think I’m on the right track using an ItemsControl control along with the ItemTemplate and DataTemplate, but I could sure use some expert advice as to how to achieve this.

If you've read this far, thank you for your time - GO PATS ;)

[edit]

Well thanks to AngelWPF (virtualization) and Rachel (everything!) I actually managed to get it working, at least for the list of plays I was providing the ItemsControl with.
Rachel, you have a great blog. The AttachedProperties entry was very useful indeed, thanks for sharing your knowledge!

At some later stage I hope to be able to add a screenshot or two which better demonstrates what I’m waffling on about ;)

As suggested, I modified the Play class with the (amongst other properties) PlayIndex for the grid positioning

public class Play
{
  public int PlayIndex { get; set; }
  public int Quarter { get; set; }
  public int Down { get; set; }
  public int YardsToGo { get; set; }
  public int Position { get; set; }
  public PlayType TypeOfPlay { get; set; }
  public PlayDetail DetailsOfPlay { get; set; }
  public PlayResult ResultOfPlay { get; set; }
  public int YardsOfPlay { get; set; }
  public double PlayLength { get; set; }
  public string Player1 { get; set; }
  public string Player2 { get; set; }
}

and to use that PlayIndex, the ItemContainerStyle was added to the ItemsControl

<ItemsControl.ItemContainerStyle>
  <Style>
    <Setter Property="Grid.Column" Value="{Binding PlayIndex}" />
    <Setter Property="Grid.Row" Value="{Binding PlayIndex}" />
  </Style>
</ItemsControl.ItemContainerStyle>

Changing the ItemsPanelTemplate from a StackPanel to a Grid also helped for this :) Now each Play is displayed next to each other as well as under each other with the respective colour. Adding a ToolTip to the ItemsControl (using the other properties in the Play class) polished it off.

As I have already stated, this works great now with a list of Play items (shortened for simplicity):

List<Play> SamplePlays = new List<Play>()
{
  new Play { PlayIndex = 0, Position = 30, YardsOfPlay = 5, PlayLength = 25 },
  new Play { PlayIndex = 1, Position = 35, YardsOfPlay = 15, PlayLength = 75 },
  new Play { PlayIndex = 2, Position = 50, YardsOfPlay = 0, PlayLength = 0 },
  new Play { PlayIndex = 3, Position = 50,  YardsOfPlay = 8, PlayLength = 40 },
  new Play { PlayIndex = 4, Position = 58,  YardsOfPlay = 1, PlayLength = 5 },
  new Play { PlayIndex = 5, Position = 59,  YardsOfPlay = 30, PlayLength = 150 }
};

But how would I go about binding what I had written at the end of the original post with regard to passing on a list of “Drives”?

Please note - with me having written this in the original post, I hope that this "allows" me to edit this post with further information and not ask a completely new question!

Given the following “Drive” class:

public class Drive
{
  public int DriveIndex { get; set; }
  public int StartPos { get; set; }
  public int EndPos { get; set; }
  public double DriveLength { get; set; }
  public DriveResult Result { get; set; }
  public List<Play> DrivePlays { get; set; }
}

Filling a list with data (using the same plays as above)

List<Drive> SampleDrives = new List<Drive>() 
{
  new Drive { DriveIndex = 0, StartPos = 30, EndPos = 49, DriveLength = 19,
              DrivePlays = new List<Play>() 
              {
                // create plays here
              }},
  new Drive { DriveIndex = 1, StartPos = 30, EndPos = 49, DriveLength = 19,
              DrivePlays = new List<Play>() 
              {
                // create plays here
              }}
};

and the ViewModel now looking like this:

public class ucDriveChartVM : ViewModelBase
{
  public List<Play> DriveDetails { get; set; }
  public List<Drive> Drives { get; set; }

  public ucDriveChartVM(ucDriveChartTP transferParameter)
  {
    this.DriveDetails = transferParameter.Plays;
    this.Drives = transferParameter.Drives;
  }
}

I obviously need to provide this ItemsControl (containing the drives) with another DataTemplate, but this DataTemplate would have to hold the plays within that list of drives. What I quickly found out is that you can’t place content in a Rectangle, so I would have to think this over :/

After experimenting a little, I bound to the DriveLength property to graphically see the length of a given drive and came up with a DataGridCell, so that I could place content in there (e.g. StackPanel).

(I know I'm not binding to anything other than the length of the drive, the Rectangle in this example is just to show something when I test!)

<DataTemplate x:Key="myDataTemplateDrives">
  <StackPanel Orientation="Horizontal" Width="{Binding DriveLength}" 
              SnapsToDevicePixels="True" Margin="0,0,1,0">
    <Border>
      <Grid>
        <StackPanel>
          <DataGridCell>
            <StackPanel Width="{Binding Path=DriveLength}">
              <Rectangle Height="10" Fill="Gray" />
            </StackPanel>
          </DataGridCell>
        </StackPanel>
      </Grid>
    </Border>
  </StackPanel>
</DataTemplate>

But I have already gone through my fourth cup of coffee and I’M having trouble binding to the List within the List object? Something like Drives.DrivePlays?!

So I'm going from a simple (thank you both)

List<Play>

binding, to a

List<Drive>

binding, which contains a

List<Play>!

called "DrivePlays" :D

Am I missing something obvious or do I need more coffee?

edit

I've explained the last part of the problem in a seperate question

Related question regarding the last part of the original question

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花想c 2024-12-15 23:45:19

首先我要说的是我对足球一无所知,所以如果我理解错误请原谅我。

首先,ItemsControl 实际上将每个项目包装在 ContentPresenter 中,因此无法通过 DataTemplate 调整项目的位置。如果您希望更改项目的位置,则需要使用 ItemContainerStyle (有关示例,请参阅 此处

由于您想要定位数据的方式,我会考虑尝试添加 Grid.Row/Grid.Column 属性到您的 Play 类,并找出后面的代码中应该包含哪些内容。然后,您可以根据 Plays 列表中的行/列数将 ItemsControl 绘制为具有列/行的网格,并将每个项目放置在适当的单元格中。 (我有一个使用附加属性定义 Grid.Rows/Columns 这里,虽然我相信他们需要一些小的修改才能绑定值......需要将 Grid 更改为GridHelpers 并将 Register 更改为 RegisterAttached

为了滚动 ItemsControl,您可以将其包装在 ScrollViewer 中。如果您还想虚拟化 ItemsControl,请查看此问题

Let me start by saying I know nothing about football, so if I understand you incorrectly forgive me.

To start with, an ItemsControl actually wraps each item in a ContentPresenter, so it won't work to adjust the positioning of your items from your DataTemplate. If you wish to alter the positioning of your items, you need to use the ItemContainerStyle (For an example, see here)

Because of the way you want to position your data, I would look into trying to add Grid.Row/Grid.Column properties to your Play class, and figure out what those should be in the code behind. Then you can draw your ItemsControl as a Grid with Columns/Rows based on the # of Rows/Columns in your Plays list, and place each item in the appropriate cell. (I have a sample of using Attached Properties to define Grid.Rows/Columns here, although I believe they need some minor modifications to be bound values... need to change Grid to GridHelpers and change Register to RegisterAttached)

For scrolling the ItemsControl, you can wrap it in a ScrollViewer. If you wish to Virtualize the ItemsControl as well, check out this question

亢潮 2024-12-15 23:45:19

我建议为了数据项的布局对齐及其虚拟化,您必须分析 WPF 下所有项目控件提供的多个选项...

  1. ItemsControlUniformGrid 作为 ItemsPanel
  2. 带有透明选择画笔的ListBox(使其看起来像项目控件)提供了固有的虚拟化。
  3. ListView同时提供了GridView的对齐布局和虚拟化。
  4. WPF DataGrid 可用于更好的选项,例如列/行虚拟化、排序等...
  5. 但是,您可以在 4.0 之前的版本中实现虚拟化 ItemsControlhttp://omniscientist.net:8081/efficientlargedatasets

I suggest for layout alignment of data items and their virtualization you have to analyze severeal options provided by all the items controls under WPF ...

  1. ItemsControl with UniformGrid as ItemsPanel.
  2. ListBox with transparent selection brush (to make it look like a items control) provides inherent virtualization.
  3. ListView provides both an alignment layout of GridView and virtualization.
  4. WPF DataGrid can be used for better options such as column / row virtualization, sorting etc...
  5. You could however, implement virtualized ItemsControl in version prior to 4.0, http://omniscientist.net:8081/efficientlargedatasets
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文