随机列表<按钮>失去与mainpage.xaml </button>的连接

时间:2013-01-13 20:24:08

标签: c# windows-phone-7

我的应用会创建一个包含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都有一个独特的边距,将其放入网格中。

This is what I have right now:

3 个答案:

答案 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)

你的逻辑是有缺陷的。您将按钮放在网格中,并使用边距定位它们。由于您使用边距来定位它们,无论您将它们添加到网格的顺序,它们的位置都不会改变。

有几种方法可以做你想做的事情:

  • 按钮列表后应用后的边距
  • 使用Stackpanel而不是网格(并删除边距)
  • 按原样使用网格:创建一些行,并将每个按钮分配到一行

    <Grid>
        <Grid.RowDefinitions>
            <Grid.RowDefinition />
            <Grid.RowDefinition />
            <Grid.RowDefinition />
            etc...
        </Grid.RowDefinitions>
    <Grid>
    

    然后在后面的代码中,设置每个按钮的行:

    Grid.SetRow(myButton, 1);
    

答案 2 :(得分:0)

您可以随机播放UIElementCollection中按钮的索引,但您可能需要切换网格类型,因为设置代码中的所有边距清晰度都不允许它随机播放。

您是否可以使用StackPanelWrapPanelUniformGrid来布局控件?

基于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);
        }
    }
}