Hier ist ein Beispiel mit der Verwendung der UniformGrid als Matt Hamilton vorgeschlagen.
Lassen Sie uns zunächst die Klassen und Daten erstellen, die wir verwenden werden. Jede Karte wird durch ein Kartenobjekt dargestellt werden, und ein Gesicht Eigenschaft hat:
public class Card
{
public string Face { get; set; }
public Card() { }
}
Als nächstes werden wir eine Klasse benötigen, die unsere Sammlung von Karten hat, und eine Eigenschaft, die uns die Anzahl der Karten festlegen kann . Für die CardCollection können wir eine ObservableCollection verwenden, da dies automatisch die Benutzeroberfläche benachrichtigt, wenn eine Karte hinzugefügt oder entfernt wird. Die NumberOfCards-Eigenschaft benötigt eine eigene Methode, um die Benutzeroberfläche zu benachrichtigen. Hierfür können wir implement die Schnittstelle INotifyPropertyChanged verwenden. Wir wollen auch eine Eigenschaft, die die Anzahl der Zeilen/Spalten repräsentiert zu verwenden, dies wird nur die Quadratwurzel unserer 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
}
Schließlich können wir dies als unsere Datacontext im Fenster gesetzt , und binden Sie an unsere Cards-Klasse im XAML. Für den XAML habe ich ein einfaches ItemsControl verwendet, so dass es nicht auswählbar ist, und ich habe das DataTemplate als eine Schaltfläche festgelegt, so dass jede Karte angeklickt werden kann, das ist alles was benötigt wird!
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>
Eine andere Sache, die ich empfehlen würde bei der Suche ist ContentControl3D Implementierung Josh Smith. Das kann Ihnen das "Flipping" Verhalten geben, das Sie in der Card Klasse implementieren möchten.
Sehr schön! +1 ... hoffe das wird "akzeptiert"! –
oh das ist super, vielen Dank! –