Я пытаюсь эмулировать схему дисков 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
}
Список получает некоторые данные… (примерные данные, я знаю, что 1-й даун получен 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 }
};
… и передается с помощью класса параметров передачи в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;
}
}
Вот xaml для ItemsPanel:
<ItemsPanelTemplate x:Key="myItemsPanelTemplate">
<StackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
Вот xamlдля ItemTemplate - обратите внимание, что я привязываюсь к 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 (virtualization) и Rachel (все!) Мне действительно удалось заставить его работать, по крайней мере для списка игр, которыми я предоставлял ItemsControl.Рейчел, у тебя отличный блог.Запись AttachedProperties действительно была очень полезна, спасибо, что поделились своими знаниями!
На более позднем этапе я надеюсь, что смогу добавить один или два снимка экрана, которые лучше демонстрируют то, о чем я болтаю;)
Как было предложено, я изменил класс Play с помощью (среди прочих свойств) PlayIndex для позиционирования сетки
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 :) Теперь каждая игра отображается рядом друг с другом, а также под другим цветом.Добавление всплывающей подсказки к ItemsControl (с использованием других свойств в классе Play) отполировало его.
Как я уже говорил, теперь это прекрасно работает со списком элементов 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;
}
}
Мне, очевидно, нужно предоставить этому 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?Что-то вроде Drives.DrivePlays?!
Итак, я иду от простого (спасибо вам обоим)
List<Play>
к привязке
List<Drive>
,который содержит
List<Play>!
, называемый «DrivePlays»: D
Я что-то упускаю из виду или мне нужно больше кофе?
edit
Я объяснил последнюю часть проблемы в отдельном вопросе
Смежный вопрос относительно последней части исходного вопроса