我是WPF的新手,所以我刚开始制作一个非常简单的记忆卡游戏,只是为了学习语法等等。游戏是所有卡面朝下的地方,你翻转两个,如果匹配则将它们移除,否则将它们重新折叠并尝试以最短的翻转次数移除所有卡片。就像我说的那样,非常简单...... :)
我的问题是,HTML中是否没有表格元素,因此我可以轻松地将卡片放在统一的布局中,而不必乱用边距?
答案 0 :(得分:10)
以下是Matt Hamilton建议的使用UniformGrid的示例。
首先,让我们创建我们将要使用的类和数据。 每张卡都将由一个Card对象表示,并具有Face属性:
public class Card
{
public string Face { get; set; }
public Card() { }
}
接下来,我们需要一个包含我们的卡片集合的类,以及一个允许我们设置卡片数量的属性。对于CardCollection,我们可以使用ObservableCollection,因为在添加或删除卡时,它会自动通知UI。 NumberOfCards属性需要它自己的方法来通知UI,为此我们可以implement 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
}
最后,我们可以将它设置为Window中的DataContext,并绑定到XAML中的Cards类。对于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>
我希望看到的另一件事是Josh Smith的ContentControl3D实现。因为这可以为你提供你想要在Card类中实现的“翻转”行为。
答案 1 :(得分:2)
我建议您为自己的方案UniformGrid。快速搜索产生了this article,其中包含一些可能有用的代码和屏幕截图。
答案 2 :(得分:0)
WPF中有一个表,这是开始使用它的好article。根据经验,WPF中的表并不那么容易使用,使用网格通常是更好的选择。