C# 动态调整二维网格的大小

C# 动态调整二维网格的大小,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在WPF中创建纸牌游戏内存。我在UI方面遇到了问题。我对其进行了设置,以便当用户选择难度时,它可以动态设置4x4甲板的大小,以方便操作,这就是我们将要讨论的概念验证。在选择不同的困难时,如何考虑网格的动态变化 这是设置难度的地方,所有卡都是为了测试目的 private void SetDifficulty(Difficulty difficulty) { //Clearing CardList CardList.Clear(); //Swit

我正在WPF中创建纸牌游戏内存。我在UI方面遇到了问题。我对其进行了设置,以便当用户选择难度时,它可以动态设置4x4甲板的大小,以方便操作,这就是我们将要讨论的概念验证。在选择不同的困难时,如何考虑网格的动态变化

这是设置难度的地方,所有卡都是为了测试目的

 private void SetDifficulty(Difficulty difficulty) {
        //Clearing CardList
        CardList.Clear();
        //Switching on the diff
        switch (difficulty) {
            case Difficulty.Easy:
                CardList = new ObservableCollection<Card>{
                    new Card {
                      Image = Resources.Bowser
                    },
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card(),
                    new Card()
                };

                break;
            case Difficulty.Medium:
                break;
            case Difficulty.Hard:
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(difficulty), difficulty, null);
        }
    }
XAML:

对于XAML中的集合,我更喜欢使用ItemsControl而不是ListBox。我还将绑定集合的宽度并添加允许包装对象的包装器面板:

<ItemsControl ItemsSource="{Binding Path=CardList} Width="{Binding CollWidth}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="viewModels:Card">
            <StackPanel Orientation="Horizontal" Width="50" Height="50" >
                <!--<Image Source="/Pictures/Luigi.jpg"></Image>-->
                <Button Content="{Binding Image, UpdateSourceTrigger=PropertyChanged}" Margin="5" Height="50" Width="50">
                </Button>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
                <!-- A WrapPanel ensures the items wrap to the next line -->
                <!-- when it runs out of room in the collection dimensions -->
                <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
现在,您可以轻松修改SetDediculty方法:

你不必担心收藏的高度。附加的将为您解决这一问题。您只需指定CollWidth,包裹面板将在每行中放置CollWidth/50按钮

您可以使用UniformGrid作为ListBox的ItemsPanel,并将其Columns或Rows属性绑定到视图模型中的属性:

<ListBox ItemsSource="{Binding CardList}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="{Binding GridSize}"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding Image}" Margin="5" Height="50" Width="50"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
XAML:


为什么不在for循环中初始化它们呢?使用UniformGrid可能更简单,例如。列和行属性支持绑定,更改绑定源值和板大小将被更新我计划这样做,我这样添加它们只是为了测试,但循环会更容易。是的,图像只是一个黑客,因为我正努力让它显示出来。不幸的是,这是我的第一个WPF项目,还不知道所有的细节。非常感谢你的提示。非常感谢。这正是我想要它做的。实际上,我最终在按钮内部抛出了一个标记,并将其绑定到Image属性,但对于它的其余部分。。“太好了!”我很高兴能帮上忙。如果您认为这是答案,我恳请您选择:谢谢:
    private int _collWidth;
    public int CollWidth {
        get { return _collWidth; }
        set {
            _collWidth = value;
            OnPropertyChanged("CollWidth");
        }
    }
private void SetDifficulty(Difficulty difficulty) {
    // this auto clears everything
    CardList = new ObservableCollection<Card>();
    //Switching on the diff
    switch (difficulty) {
        case Difficulty.Easy:
            // set the width in each level of difficulty to allow wrapper to make nice looking grid
            CollWidth = 200; // (button width is 50) * 4 buttons = 200
            for(int i=0;i<16;i++)
                CardList.Add(new Card()); // or whatever constructor
            break;
        case Difficulty.Medium:
            CollWidth = 250; // (button width is 50) * 5 buttons = 250
            for(int i=0;i<25;i++)
                CardList.Add(new Card()); // or whatever constructor
            break;
        case Difficulty.Hard:
            CollWidth = 300; // (button width is 50) * 6 buttons = 300
            for(int i=0;i<36;i++)
                CardList.Add(new Card()); // or whatever constructor
            break;
        default:
            throw new ArgumentOutOfRangeException(nameof(difficulty), difficulty, null);
    }
}
<ListBox ItemsSource="{Binding CardList}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="{Binding GridSize}"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding Image}" Margin="5" Height="50" Width="50"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
public class Card
{
    public ImageSource Image { get; set; }
    ...
}

...
var card = new Card
{
    Image = new BitmapeImage(new Uri("pack://application:,,,/Picures/Luigi.jpg"))
};
<ListBox.ItemTemplate>
    <DataTemplate>
        <Button Margin="5" Height="50" Width="50">
            <Image Source="{Binding Image}"/>
        </Button>
    </DataTemplate>
</ListBox.ItemTemplate>