@ZelibobA1706

Каким способом лучше позиционировать элементы?

Есть задание написать пятнашки с непостоянным количеством фишек. Как лучше всего сделать позиционирование элементов в окне? Хотелось бы что-то вроде сетки с биндингом.
Решил попробовать сделать через ItemsControl и Grid, но все элементы помещаются только в одну ячейку.
<ItemsControl ItemsSource="{Binding FieldCollection}" Margin="10">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid Name="MainGrid">
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border CornerRadius="5" Margin="2"  Grid.Column="{Binding PositionX}" Grid.Row="{Binding PositionX}"  BorderBrush="#FFFF1212" Background="#FFB98787">
                       <Label Content="{Binding Value}"></Label>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

p8l_JmqVX1w.jpg
Решил это таким способом:
<ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Grid.Column"
                    Value="{Binding PositionX}" />
                <Setter Property="Grid.Row"
                    Value="{Binding PositionY}" />
            </Style>
        </ItemsControl.ItemContainerStyle>

Но так и не придумал как сделать, что бы строки и столбцы сетки задавались автоматически.
  • Вопрос задан
  • 393 просмотра
Решения вопроса 1
yarosroman
@yarosroman Куратор тега C#
C# the best
Самое простое, GridView, в ItemsPanelTemplate, задаем шаблон панели. А тут придется переписать поведение панели. Делаем новой компонент, GamePanel и переопределяем там ArrangeOverride и MeasureOverride, добавляем свойства нужные и тд.
class GamePanel:Panel
        {
        public int ItemsPerWidth
        {
            get { return (int)GetValue(ItemWidthProperty); }
            set { SetValue(ItemWidthProperty, value); }
        }
        public static readonly DependencyProperty ItemsPerWidthProperty =
            DependencyProperty.Register(nameof(ItemsPerWidth), typeof(int), typeof(GamePanel), new PropertyMetadata(null));

        public int ItemsPerHeight
        {
            get { return (int)GetValue(ItemWidthProperty); }
            set { SetValue(ItemWidthProperty, value); }
        }
        public static readonly DependencyProperty ItemPerHeightProperty =
            DependencyProperty.Register(nameof(ItemsPerHeight), typeof(int), typeof(GamePanel), new PropertyMetadata(null));


        protected override Size ArrangeOverride(Size finalSize)
        {
        }

        protected override Size MeasureOverride(Size availableSize)
        {
        }

    }


про ArrangeOverride и MeasureOverride тут

и в Xaml
<GridView ItemsSource="{Binding ShopItems}" ItemContainerStyle="{StaticResource ShopGridViewItemExpanded}" Loaded="GridView_Loaded">
            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <controls:GamePanel ItemsPerWidth="4" ItemsPerHeight="4"></controls:VariableHeightPanel>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
            <GridView.ItemTemplate>
                <DataTemplate>
                      <Border ..цвет, заливка.......>
                              <TextBlock ......тут номер />
                     </Border>
                 </DataTemplate>
            </GridView.ItemTemplate>
        </GridView>


вот и все. теперь во вью модели у вас будет коллекция фишек (типа
public class GameItem
{
    public int Id { get;set; }
    public string Text { get; set;}
    public bool IsEmpty {get; set;}
   .... ну и далее, например цвет, картинка и тд.
}

public class ViewModel
{
   private readonly ObservableCollection<GameItem> _gameItems = new ObservableCollection<GameItem>();

   public ObservableCollection<GameItem> GameItems => return _gameItems;
}


естественно можете задать свойства для привязки ItemsPerHeight и ItemsPerWidth.
все просто? новая игра? очищаем коллекцию, заполняем новыми фишками (не забываем про пустую), проверить на конец игры, проходим по списку и смотрим по порядку ли элементы.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы