Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf ItemsControl(虚拟化足球驱动器信息)_Wpf_Overlay_Itemscontrol_Offset_Scrollable - Fatal编程技术网

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

Wpf ItemsControl(虚拟化足球驱动器信息),wpf,overlay,itemscontrol,offset,scrollable,Wpf,Overlay,Itemscontrol,Offset,Scrollable,我正在尝试模拟NFL的驾驶图表,以可视化游戏中的一些驾驶数据。这里可以看到一个我大致尝试模仿的例子,由nfl.com提供。我正在努力实现以下目标: 展示比赛场地 在运动场的顶部绘制数据 当我把鼠标移到某物上时,我想触发一个事件,例如。 工具提示 这里是我现在的位置,首先是xaml: <StackPanel x:Name="myStackPanel" Orientation="Vertical"> <StackPanel.Background> <Imag

我正在尝试模拟NFL的驾驶图表,以可视化游戏中的一些驾驶数据。这里可以看到一个我大致尝试模仿的例子,由nfl.com提供。我正在努力实现以下目标:

展示比赛场地 在运动场的顶部绘制数据 当我把鼠标移到某物上时,我想触发一个事件,例如。 工具提示 这里是我现在的位置,首先是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>
PlayType是一个枚举:

public enum PlayType
{
  Run,
  Pass,
  Penalty,
  Punt,
  FieldGoal
}
列表得到了一些数据…样本数据,我知道已经得到了第一个下降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 }
};
…将其分配给DriveDetails属性的位置

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

    public ucDriveChartVM(ucDriveChartTP transferParameter)
    {
        this.DriveDetails = transferParameter.Plays;
    }
}
为了使用该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更改为网格也有助于实现这一点:现在每个播放都以各自的颜色显示在彼此旁边和下方。使用Play类中的其他属性将工具提示添加到ItemsControl中,使其更加完美

正如我已经说过的,为了简单起见,这项功能现在非常有效,并缩短了播放项目列表:

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 }
};
但是,我将如何绑定我在原始帖子末尾所写的关于传递“驱动器”列表的内容呢

请注意-我已经在原来的帖子中写了这篇文章,我希望这能让我编辑这篇文章,并提供更多信息,而不是问一个全新的问题

给定以下“驱动”等级:

public class Play
{
  public int Quarter { get; set; }
  public int Result { get; set; }
  public PlayType TypeOfPlay { get; set; }
  public double WidthOfPlay { get; set; }
}
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;
  }
}
显然,我需要为包含驱动器的ItemsControl提供另一个DataTemplate,但此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<Play>
绑定到

List<Drive>
绑定,其中包含

List<Play>!
名为DrivePlays:D

我是错过了一些明显的东西还是我需要更多的咖啡

编辑

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


我建议对于数据项的布局对齐及其虚拟化,您必须分析WPF下所有项控件提供的严重选项

UniformGrid为ItemsPanel的ItemsControl。 ListBox带有透明的选择笔刷,使其看起来像一个items控件,提供了固有的虚拟化。 ListView提供GridView和虚拟化的对齐布局。 WPF DataGrid可用于更好的选项,如列/行虚拟化、排序等。。。 但是,您可以在4.0之前的版本中实现虚拟化ItemsControl,
让我先说我对足球一无所知,所以如果我理解错误,请原谅我

首先,ItemsControl实际上将每个项目包装在ContentPresenter中,因此无法从DataTemplate调整项目的位置。如果希望更改项目的位置,则需要使用ItemContainerStyle作为示例,请参见

由于您希望定位数据的方式,我将尝试向Play类中添加Grid.Row/Grid.Column属性,并找出这些属性在代码中应该是什么。然后,您可以根据播放列表中的行/列数,将ItemsControl绘制为具有列/行的网格,并将每个项放置在相应的单元格中。我有一个使用附加属性定义Grid.Rows/Columns的示例,尽管我相信它们需要一些小的修改才能绑定值。。。需要将网格更改为GridHelpers,并将Register更改为RegisterAttached


要滚动ItemsControl,可以将其包装在ScrollViewer中。如果您也希望虚拟化ItemsControl,请查看

Hello AngelWPF,谢谢您的评论。我认为UniformGrid不适合,因为剧本的长度可能不同。我认为使用ItemsControl,我实际上实现了与使用ListBox控件和透明画笔相同的功能,但我必须更深入地研究虚拟化。你提供给我的链接毁了我的Firefox,真丢脸,哈哈,我还有很多东西要读,再次感谢你!这就是为什么你有时应该相信我-公司政策恐怕今晚我会在家里看一看:迪洛·瑞秋,每次都是
我相信我已经学到了一些WPF的东西,随之而来的是一些新的东西-谢谢!ItemContainerStyle看起来确实很有趣,向类中添加建议的属性没有问题。我唯一想知道的是xaml和列数,因为一个驱动器理论上可以有无限的播放次数,实际上最多在15到20之间,所以我有点不确定如何在网格中创建列数。。。。你也给了我很多东西要看,还有一些很棒的链接,所以如果时间允许,我明天会仔细看看。至于你缺乏足球知识,我应该是一个没有知识的人,因为我出生在英国,现在在德国工作:再次感谢你的评论@Dave很高兴这对您有所帮助:一旦您设置了Grid.Row/Grid.Column属性,您就可以编写一些东西来获取每个属性的最大值,并将其绑定到ItemsPanel网格的RowCount/ColumnCount属性。
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 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<Play>
List<Drive>
List<Play>!