Макет таблицы в WPF - PullRequest
       10

Макет таблицы в WPF

7 голосов
/ 05 июня 2009

Я очень новичок в WPF, поэтому я только начал делать очень простую карточную игру для памяти, чтобы изучить синтаксис и тому подобное. В игре все карты обращены вниз, вы переворачиваете две карты, и, если они совпадают, вы удаляете их, в противном случае переворачиваете их и пытаетесь удалить все карты за наименьшее количество бросков. Как я уже сказал, очень просто ...:)

У меня вопрос: нет ли элемента таблицы, как в HTML, чтобы я мог легко поместить карточки в единый макет вместо того, чтобы возиться с полями?

Ответы [ 3 ]

10 голосов
/ 05 июня 2009

Вот пример использования UniformGrid, как предложил Мэтт Гамильтон.

Во-первых, давайте создадим классы и данные, которые мы будем использовать. Каждая карта будет представлена ​​объектом Card и будет иметь свойство Face:

public class Card
{
    public string Face { get; set; }
    public Card() { }
}

Далее нам понадобится класс с нашей коллекцией карт, а также свойство, которое позволяет нам устанавливать количество карт. Для CardCollection мы можем использовать ObservableCollection , поскольку она автоматически уведомит пользовательский интерфейс при добавлении или удалении карты. Свойству NumberOfCards потребуется собственный метод для уведомления пользовательского интерфейса, для этого мы можем реализовать интерфейс INotifyPropertyChanged . Мы также хотим, чтобы свойство, которое представляет число строк / столбцов, использовалось, это будет просто квадратный корень из наших NumberOfCards:

public class Cards : INotifyPropertyChanged
{
    private int myNumberOfCards;
    public int NumberOfCards
    {
        get { return this.myNumberOfCards; }
        set
        {
            this.myNumberOfCards = value;
            NotifyPropertyChanged("NumberOfCards");

            // Logic is going in here since this is just an example,
            // Though I would not recomend hevily modifying the setters in a finalized app.
            while (this.myNumberOfCards > CardCollection.Count)
            {
                CardCollection.Add(new Card { Face = (CardCollection.Count + 1).ToString() });
            }
            while (this.myNumberOfCards < CardCollection.Count)
            {
                CardCollection.RemoveAt(CardCollection.Count - 1);
            }

            NotifyPropertyChanged("CardColumns");
        }
    }
    public int CardColumns
    {
        get
        {
            return (int)Math.Ceiling((Math.Sqrt((double)CardCollection.Count)));
        }
    }
    private ObservableCollection<Card> myCardCollection;
    public ObservableCollection<Card> CardCollection
    {
        get
        {
            if (this.myCardCollection == null)
            { this.myCardCollection = new ObservableCollection<Card>(); }
            return this.myCardCollection;
        }
    }
    public Cards(int initalCards)
    {
        NumberOfCards = initalCards;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion
}


Наконец, мы можем установить это как наш DataContext в окне и привязать к нашему классу Cards в XAML. Для XAML я использовал простой ItemsControl, чтобы его нельзя было выбрать, и я установил DataTemplate в качестве кнопки, чтобы можно было нажимать на каждую карту, вот и все, что нужно!

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        this.DataContext = new Cards(25);
    }
}

<Window x:Class="Sample_BoolAnimation.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1"
    Height="300"
    Width="300">
    <Grid>
        <DockPanel>
            <DockPanel DockPanel.Dock="Top">
                <TextBlock Text="Number of Cards:" />
                <TextBox Text="{Binding NumberOfCards, UpdateSourceTrigger=PropertyChanged}" />
            </DockPanel>
            <ItemsControl ItemsSource="{Binding CardCollection}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Columns="{Binding CardColumns}" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Face}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DockPanel>
    </Grid>
</Window>

Другая вещь, на которую я бы порекомендовал взглянуть, - это реализация ContentControl3D Джоша Смита. Так как это может дать вам поведение «переворачивания», которое вы ищете для реализации в классе Card, очень приятно.

2 голосов
/ 05 июня 2009

Я бы порекомендовал UniformGrid для вашего сценария. В результате быстрого поиска была получена эта статья , включающая код и снимки экрана, которые могут помочь.

0 голосов
/ 05 июня 2009

В WPF есть таблица, вот хорошая статья о начале работы с ней. Исходя из опыта, таблица в WPF не так проста в использовании, и использование Grid обычно является лучшим вариантом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...