[英]Can I access XAML elements in an array in the codebehind?
I've been looking around but I haven't been able to find anything on this. 我一直在环顾四周,但至今仍找不到任何东西。 I am trying to get started making Windows 8.1 apps in C# with Visual Studio 2013 Pro.
我正在尝试开始使用Visual Studio 2013 Pro在C#中制作Windows 8.1应用程序。 I want to be able to access multiple elements (particularly buttons or text blocks) in an array because this is more convenient for developing things like board games.
我希望能够访问数组中的多个元素(尤其是按钮或文本块),因为这对于开发诸如棋盘游戏之类的东西更加方便。 For instance, if I were developing tic-tac-toe, I might use a series of buttons like this:
例如,如果我正在开发井字游戏,我可能会使用一系列类似这样的按钮:
<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/>
Now for the function that would check for a win, I would have to check all possible combinations like this is in the code behind: 现在,对于要检查获胜的函数,我将必须检查所有可能的组合,如下所示:
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
}
This type of code would be extremely cumbersome. 这种类型的代码将非常麻烦。 I would like to write it instead in a way that lets me check the array with for loops.
我想以一种让我用for循环检查数组的方式来编写它。
I realize that with tic-tac-toe, it is fairly easy to code it using brute force, but this was the first example that came to my head. 我意识到,使用井字游戏很容易用蛮力编写代码,但这是我想到的第一个示例。 Other games like Reversi or Go would not work well like this because of either the sheer size or the fact that pieces placed can change other cells than the one they were placed on.
诸如Reversi或Go之类的其他游戏由于其庞大的尺寸或放置的棋子可能会改变其他单元格而不是放置它们的事实而不能像这样很好地工作。
Any help with this would be greatly appreciated. 任何帮助,将不胜感激。
This is not the correct way to use WPF. 这不是使用WPF的正确方法。 WPF is designed to use data binding....creating and manipulating UI elements directly is bad form.
WPF设计为使用数据绑定。...直接创建和操作UI元素是一种不好的形式。 There are more posts/discussion/questions about this than you can imagine and I'll leave you to research them for yourself.
关于此的更多帖子/讨论/问题超出了您的想象,我将让您自己研究它们。 In the mean time this is how you use WPF "properly":
同时,这是您“正确”使用WPF的方式:
First use NuGet to add MVVM lite to your project so that you get the ViewModelBase
class and create a view model for a single cell: 首先使用NuGet将MVVM lite添加到项目中,以便获得
ViewModelBase
类并为单个单元创建视图模型:
public class Cell : ViewModelBase
{
private string _Text;
public string Text
{
get { return _Text; }
set { _Text = value; RaisePropertyChanged(() => this.Text); }
}
}
One level up you'll want a main model to encapsulate an array of these, this is where you will typically do all your game logic: 在更高级别上,您将需要一个主模型来封装这些模型的数组,这通常是您执行所有游戏逻辑的地方:
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() })
);
}
}
Notice that all I'm doing at the moment is creating a 100-element collection of cells. 请注意,我目前所做的只是创建一个包含100个元素的单元格集合。 This main view model becomes the one that you assign to your window's data context:
这个主视图模型成为您分配给窗口数据上下文的模型:
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainModel();
}
Now your XAML controls need to bind to this data. 现在,您的XAML控件需要绑定到该数据。 ItemsControl is used to render a collection of elements so use one of those and bind it to your array.
ItemsControl用于呈现元素的集合,因此请使用其中之一并将其绑定到您的数组。 You want them displayed in a 2D grid so replace the ItemsPanelTemplate with a WrapPanel.
您希望它们显示在2D网格中,因此用WrapPanel替换ItemsPanelTemplate。 Finally add a DataTemplate for your Cell class so that a button gets drawn for each cell:
最后,为您的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>
That's how you use WPF. 这就是您使用WPF的方式。 Your logic is stored entirely in the view model and it's completely decoupled from the view.
您的逻辑完全存储在视图模型中,并且与视图完全分离。 Here's what this particular code displays, it should be pretty self-evident how flexible this code is and easy to change:
这是此特定代码显示的内容,这不难理解该代码的灵活性和易于更改:
That's very possible. 那很有可能。 Simply declare an array variable :
只需声明一个数组变量:
private Button[] _buttonArray;
populate the array once, maybe in constructor : 一次填充数组,也许在构造函数中:
_buttonArray = new[] {Cell00, Cell01, .... , Cell22};
And all of the buttons are now accessible through _buttonArray
. 现在可以通过
_buttonArray
访问所有按钮。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.