我可以在代码隐藏中访问数组中的XAML元素吗?

时间:2014-02-08 02:03:40

标签: c# wpf xaml visual-studio-2013 windows-8.1

我一直在四处寻找,但我一直无法找到任何相关信息。我正在尝试使用Visual Studio 2013 Pro在C#中开始制作Windows 8.1应用程序。我希望能够访问数组中的多个元素(特别是按钮或文本块),因为这对于开发诸如棋盘游戏之类的东西更方便。例如,如果我正在开发tic-tac-toe,我可能会使用一系列这样的按钮:

<Grid>
    <Button Name="Cell00"/>
    <Button Name="Cell01"/>
    <Button Name="Cell02"/>
    <Button Name="Cell10"/>
    <Button Name="Cell11"/>
    <Button Name="Cell12"/>
    <Button Name="Cell20"/>
    <Button Name="Cell21"/>
    <Button Name="Cell22"/>
<Grid/>

现在对于检查胜利的功能,我必须检查所有可能的组合,如下所示:

private bool CheckForWin()
{
    if((Cell00 == Cell01) && (Cell01 == Cell02) && isNotBlank(Cell02)) return true;
    if((Cell10 == Cell11) && (Cell11 == Cell12) && isNotBlank(Cell12)) return true
    ...
    return false; //if none of the win conditions pass
}

这种类型的代码非常麻烦。我想以一种让我用for循环检查数组的方式来编写它。

我意识到使用井字游戏,使用蛮力来编码它相当容易,但这是第一个出现在我脑海中的例子。像Reversi或Go这样的其他游戏不会像这样运作得很好,因为它的大小或放置的碎片可以改变其他细胞而不是它们所放置的细胞。

对此的任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

这不是使用WPF的正确方法。 WPF旨在使用数据绑定....直接创建和操作UI元素是不好的形式。关于这一点的帖子/讨论/问题比你想象的还要多,我会让你自己研究一下。与此同时,这就是“正确”使用WPF的方式:

首先使用NuGet将MVVM lite添加到项目中,以便获得ViewModelBase类并为单个单元格创建视图模型:

public class Cell : ViewModelBase
{
    private string _Text;
    public string Text
    {
        get { return _Text; }
        set { _Text = value; RaisePropertyChanged(() => this.Text); }
    }
}

一级你需要一个主模型来封装这些数组,这是你通常会做所有游戏逻辑的地方:

public class MainModel : ViewModelBase
{
    private ObservableCollection<Cell> _Cells;
    public ObservableCollection<Cell> Cells
    {
        get { return _Cells; }
        set { _Cells = value; RaisePropertyChanged(() => this.Cells); }
    }

    public MainModel()
    {
        this.Cells = new ObservableCollection<Cell>(
            Enumerable.Range(1, 100)
                .Select(i => new Cell { Text = i.ToString() })
        );
    }
}

请注意,我现在正在做的就是创建一个100个元素的单元格集合。此主视图模型将成为您分配给窗口数据上下文的模型:

public MainWindow()
{
    InitializeComponent();
    this.DataContext = new MainModel();
}

现在您的XAML控件需要绑定到此数据。 ItemsControl用于呈现元素集合,因此请使用其中一个元素并将其绑定到您的数组。您希望它们显示在2D网格中,因此将ItemsPanelTemplate替换为WrapPanel。最后为Cell类添加一个DataTemplate,以便为每个单元格绘制一个按钮:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:Cell}">
        <Button Width="32" Height="32" Content="{Binding Text}"/>
    </DataTemplate>
</Window.Resources>

<ItemsControl ItemsSource="{Binding Cells}" Width="320" Height="320" HorizontalAlignment="Center" VerticalAlignment="Center">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel  />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

这就是你使用WPF的方式。您的逻辑完全存储在视图模型中,并且它与视图完全分离。以下是此特定代码显示的内容,这段代码的灵活性和易于更改应该是不言而喻的:

enter image description here

答案 1 :(得分:0)

这很有可能。只需声明一个数组变量:

private Button[] _buttonArray;

填充数组一次,也许在构造函数中填充:

_buttonArray = new[] {Cell00, Cell01, .... , Cell22};

现在可以通过_buttonArray访问所有按钮。

相关问题