我的应用会创建一个包含20个按钮的列表,这些按钮位于mainpage.xaml:
上private List<Button> CreateList()
{
for (int i = 0; i <= 19; i++)
{
string name = string.Format("button{0}", i+1);
Button buttt = new Button();
buttt.Name = name;
buttt.Content = i + 1;
buttt.Height = 72;
buttt.HorizontalAlignment = HorizontalAlignment.Left;
buttt.VerticalAlignment = VerticalAlignment.Top;
buttt.Width = 88;
buttt.Click += new RoutedEventHandler(this.button_Click);
GameGrid.Children.Add(buttt);
myList.Insert(i, buttt);
}
现在如果我试图改变这个列表,它似乎失去了与页面上实际按钮的连接。
private void Shuffle(List<Button> list)
{
//list[1].Content = "DING!";
Random rand = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rand.Next(n + 1);
Button value = list[k];
list[k] = list[n];
list[n] = value;
}
}
请注意,如果我取消注释//list[1].Content = "DING!";
并注释掉此方法的其余部分,则会在屏幕上更改按钮的内容。所以我假设在洗牌过程中链接被破坏了。
所以我的问题是,当我运行此代码时,按钮会显示但仍然是从1到20的顺序,而不是像我想要的那样随意洗牌。
感谢您的帮助!
编辑:以下是克里斯建议的完整代码:
private List<Button> CreateList(List<Marginz> myMargin)
{
for (int i = 0; i <= 19; i++)
{
string name = string.Format("button{0}", i+1);
Button buttt = new Button();
buttt.Name = name;
buttt.Content = i + 1;
buttt.Height = 72;
buttt.HorizontalAlignment = HorizontalAlignment.Left;
buttt.VerticalAlignment = VerticalAlignment.Top;
buttt.Width = 88;
buttt.Click += new RoutedEventHandler(this.button_Click);
Thickness myThickness = new Thickness();
myThickness.Left = myMargin[i].left;
myThickness.Top = myMargin[i].top;
myThickness.Right = myMargin[i].right;
myThickness.Bottom = myMargin[1].bottom;
buttt.Margin = myThickness;
//GameGrid.Children.Add(buttt);
myList.Insert(i, buttt);
}
return myList;
}
这就是所谓的地方:
private void EasyButton_Click(object sender, RoutedEventArgs e)
{
DifficultyCanvas.Visibility = System.Windows.Visibility.Collapsed;
ReadyCanvas.Visibility = System.Windows.Visibility.Visible;
//set difficulty attributes
difficulty = "Easy";
var myMarg = CreateMarginList(marg);
var buttons = CreateList(myMarg);
Shuffle(buttons);
foreach (var button in buttons)
{
GameGrid.Children.Add(button);
}
}
编辑以获得更多解释: 关于边缘。我创建了一个名为Marginz的课程:
public class Marginz
{
public Marginz()
{
//Constructor
}
public int left { get; set; }
public int top { get; set; }
public int right { get; set; }
public int bottom { get; set; }
}
“marg”是此类型的列表:
List<Marginz> marg = new List<Marginz>(20);
CreateMarginList()执行此操作:
public List<Marginz> CreateMarginList(List<Marginz> myMarg)
{
Marginz one = new Marginz();
one.left = 28;
one.top = 186;
one.right = 0;
one.bottom = 0;
myMarg.Insert(0, one);
Marginz two = new Marginz();
two.left = 133;
two.top = 186;
two.right = 0;
two.bottom = 0;
myMarg.Insert(1, two);
一直到二十岁等等。然后return myMarg;
因此,每个Button都有一个独特的边距,将其放入网格中。
答案 0 :(得分:1)
改组myList集合不会改变它们在页面上显示的顺序。这取决于您在CreateList方法中将它们添加到GameGrid的顺序。您可以做的是创建所有内容,随机播放列表,然后将它们添加到Children列表中。
请删除GameGrid.Children.Add
中的CreateList
来电(注意,我在那里调整了代码,我假设您没有发布完整代码)
private List<Button> CreateList()
{
var myList = new List<Button>();
for (int i = 0; i <= 19; i++)
{
string name = string.Format("button{0}", i+1);
Button buttt = new Button();
buttt.Name = name;
buttt.Content = i + 1;
buttt.Height = 72;
buttt.HorizontalAlignment = HorizontalAlignment.Left;
buttt.VerticalAlignment = VerticalAlignment.Top;
buttt.Width = 88;
buttt.Click += new RoutedEventHandler(this.button_Click);
myList.Add(buttt);
}
return myList;
}
执行随机播放,然后添加它们:
var buttons = CreateList();
Shuffle(buttons);
foreach(var button in buttons)
{
GameGrid.Children.Add(button);
}
编辑:根据您发布的完整代码,问题在于因为所有按钮都在Grid
控件中,所以它们的位置取决于和他们的Margin
(控制他们在该单元格中的位置)。如果您没有明确定义它们没有的行/列,那么它们将被假定为在第一行/列中。在这种情况下,他们的边缘没有改组,决定了他们的定位。
我认为在这种情况下,要么使用单元格构建Grid,要么最容易:在创建列表之前,只需将myMargin
列表改为shuffle!按钮将按顺序添加,但它们将被赋予随机位置。
var myMargin = CreateMargins(); //wherever that's done
Shuffle(myMargin); //you'll have to change the signature to work against List<Thickness> instead
var buttons = CreateList(myMargin); //add back the GameGrid.Children.Add call
//notice, no longer a call to shuffle the buttons
可能不是最佳解决方案,但我认为这会给你带来与之相同的效果。
答案 1 :(得分:0)
你的逻辑是有缺陷的。您将按钮放在网格中,并使用边距定位它们。由于您使用边距来定位它们,无论您将它们添加到网格的顺序,它们的位置都不会改变。
有几种方法可以做你想做的事情:
按原样使用网格:创建一些行,并将每个按钮分配到一行
<Grid>
<Grid.RowDefinitions>
<Grid.RowDefinition />
<Grid.RowDefinition />
<Grid.RowDefinition />
etc...
</Grid.RowDefinitions>
<Grid>
然后在后面的代码中,设置每个按钮的行:
Grid.SetRow(myButton, 1);
答案 2 :(得分:0)
您可以随机播放UIElementCollection
中按钮的索引,但您可能需要切换网格类型,因为设置代码中的所有边距清晰度都不允许它随机播放。
您是否可以使用StackPanel
,WrapPanel
或UniformGrid
来布局控件?
基于UniformGrid
的示例(除非您在控件上设置了边距,否则它将适用于所有网格。)
我知道这不是你当前问题的答案,但它可能会指出你正确的方向。
private void Shuffle(UIElementCollection list)
{
Random rand = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rand.Next(n + 1);
Button value = list.OfType<Button>().ElementAt(n);
list.Remove(value);
list.Insert(k, value);
}
}
示例:
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="199" Width="206" Name="UI">
<Grid>
<UniformGrid Name="GameGrid" Margin="0,48,0,0" Height="112" VerticalAlignment="Top">
<Button Content="Button 1" />
<Button Content="Button 2" />
<Button Content="Button 3" />
<Button Content="Button 4" />
<Button Content="Button 5" />
</UniformGrid>
<Button Content="Shuffle" Height="23" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>
代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Shuffle(GameGrid.Children);
}
private void Shuffle(UIElementCollection list)
{
Random rand = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rand.Next(n + 1);
Button value = list.OfType<Button>().ElementAt(n);
list.Remove(value);
list.Insert(k, value);
}
}
}