简体   繁体   English

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

[英]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.

相关问题 访问 XAML 中的代码隐藏变量 - Access codebehind variable in XAML 如何访问 WPF 代码隐藏中 ContentControl DataTemplate 中的 object,或者如何在 xaml 中设置 CefSharp DownloadHandler - How can I access an object that is in a ContentControl DataTemplate in WPF codebehind, or how do I set a CefSharp DownloadHandler in xaml 从 CodeBehind 访问 DataTemplate 中的 XAML 控件? - Access XAML Control In DataTemplate From CodeBehind? CollectionViewSource在XAML中不能是DataBound,但在CodeBehind中可以吗? - CollectionViewSource can't be DataBound in XAML but can in CodeBehind? 如何在代码隐藏中访问在XAML中创建的DataContext类实例? - How to access DataContext class instance created in XAML in codebehind? 尝试从代码隐藏中按名称访问xaml“ local:”控件时出错 - Error trying to access xaml “local:” control by name from codebehind 可以从代码隐藏全局访问任何XAML窗口对象吗? - Possible to access any XAML Window Object globally from codebehind? 在代码隐藏中初始化一些静态资源,并可以在XAML(WPF)中访问它们 - Init some static resources in codebehind and have access to them in XAML (WPF) 当背后的代码包含IValueConverter实现时,如何在XAML中访问Converter - How to access a Converter in XAML when the codebehind contains the IValueConverter implementation 我正在使用WPF,我有DataTemplate,我想访问如何使用此代码的代码? - I am using WPF and I have DataTemplate that is i want to access into the codebehind how I can use this?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM