C# 洗牌列表<;按钮>;与mainpage.xaml的连接中断

C# 洗牌列表<;按钮>;与mainpage.xaml的连接中断,c#,windows-phone-7,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();

我的应用程序创建了一个包含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 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);
List marg=新列表(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);
public List CreateMarginList(List myMarg)
{
Marginz one=新的Marginz();
1.左=28;
1.top=186;
1.右=0;
1.1=0;
我的保证金插入(0,一);
Marginz two=新的Marginz();
2.左=133;
2.top=186;
2.右=0;
2.0=0;
我的保证金插入(1,2);
一直到20。然后
返回myMarg;
因此,每个按钮都有一个独特的边距,将其放置在网格中


洗牌myList集合不会改变它们在页面上的显示顺序。这取决于您在CreateList方法中将它们添加到GameGrid中的顺序。您可以做的是全部创建它们,洗牌列表,然后将它们添加到子列表中

因此,删除
GameGrid.Children.Add
调用
CreateList
(注意,我对那里的代码做了一些调整,我假设你没有发布完整的代码)

编辑:从您发布的完整代码来看,问题在于,由于所有按钮都位于
网格
控件中,因此它们的位置取决于它们所在的行/列及其
边距
(控制它们在该单元格中的位置)。如果您没有明确定义它们的行/列(您没有定义),则假定它们位于第一行/列中。在这种情况下,它们的边距(未洗牌)指示它们的位置

我认为在这种情况下,要么用单元格构建网格,要么最简单:在创建列表之前,只需洗牌
myMargin
列表!按钮将按顺序添加,但它们将被随机分配位置

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
var myMargin=CreateMargins();//无论在何处执行此操作
Shuffle(myMargin);//您将不得不更改签名以与列表相对应
var buttons=CreateList(myMargin);//添加回GameGrid.Children.add调用
//请注意,不再调用洗牌按钮

可能不是最好的解决方案,但我认为这会给您带来与您所期望的效果相同的效果。

您的逻辑有缺陷。您将按钮放在网格中,并使用边距对其进行定位。由于您使用边距对其进行定位,因此无论您以何种顺序将其添加到网格中,它们的位置都不会改变

有几种方法可以实现您的目标:

  • 在按钮列表被洗牌后应用边距
  • 使用Stackpanel而不是网格(并删除边距)
  • 按预期使用网格:创建一些行,并将每个按钮指定给一行

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

您可以在
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);
    }
}
private void Shuffle(UIElementCollection列表)
{
Random rand=新的Random();
int n=list.Count;
而(n>1)
{
n--;
int k=下一个随机数(n+1);
按钮值=list.OfType().ElementAt(n);
列表。删除(值);
列表。插入(k,值);
}
}
例如:

<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>

代码:

公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,路由目标)
{
洗牌(GameGrid.Children);
}
私有无效洗牌(UIElementCollection列表)
{
Random rand=新的Random();
int n=list.Count;
而(n>1)
{
n--;
int k=下一个随机数(n+1);
按钮值=list.OfType().ElementAt(n);
列表。删除(值);
列表。插入(k,值);
}
}
}

洗牌
myList
集合不会改变它们在页面上的显示顺序。这取决于您在
CreateList
方法中将它们添加到游戏网格中的顺序。编辑:您可以做的是将它们全部创建,洗牌列表,然后将它们添加到子列表中。感谢您的快速回复。您说的是什么很有意义!但由于某些原因,它仍然不起作用。按钮在屏幕上仍按1到20的顺序显示?@davekats您可以在调试器中设置断点,并确保
myList
被洗牌(检查它们的
内容
)在添加到GameGrid之前?另外,您是否删除了
GameGrid.Children.Add
调用
CreateList
?是的,我已经完成了这两件事。myList中的按钮[1]内容值为5,我在CreateList中注释掉了GameGrid.Children.Add调用。你能发布
CreateList
的实际完整代码吗?还有,
GameGrid
是什么类?我发布了完整代码,GameGrid是在mainpage.xaml页面上创建的System.Windows.Controls.Grid。我做了你的第一个建议(在按钮列表被洗牌后应用边距)使用我创建的ApplyMargins()方法。这对我最有效,谢谢!
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
<Grid>
    <Grid.RowDefinitions>
        <Grid.RowDefinition />
        <Grid.RowDefinition />
        <Grid.RowDefinition />
        etc...
    </Grid.RowDefinitions>
<Grid>
Grid.SetRow(myButton, 1);
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);
        }
    }
}