FindName返回null [英] FindName returning null

查看:125
本文介绍了FindName返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写学校一个简单的井字游戏。分配在C ++中,但老师给了我使用C#和WPF是一个挑战许可。我已经得到了所有完成了比赛逻辑和形式大多是完整的,但我已经碰壁。我目前使用的是标签来表明谁是轮到了,我要当一名球员做一个有效的举措来改变它。据应用=代码+标记,我应该能够使用 FindName 窗口类的方法。然而,它使返回。下面的代码:

I'm writing a simple tic tac toe game for school. The assignment is in C++, but the teacher has given me permission to use C# and WPF as a challenge. I've gotten all the game logic finished and the form mostly complete, but I've run into a wall. I'm currently using a Label to indicate who's turn it is, and I want to change it when a player makes a valid move. According to Applications = Code + Markup, I should be able to use the FindName method of the Window class. However, it keeps returning null. Here's the code:

public TicTacToeGame()
{
    Title = "TicTacToe";
    SizeToContent = SizeToContent.WidthAndHeight;
    ResizeMode = ResizeMode.NoResize;

    UniformGrid playingField = new UniformGrid();
    playingField.Width = 300;
    playingField.Height = 300;
    playingField.Margin = new Thickness(20);

    Label statusDisplay = new Label();
    statusDisplay.Content = "X goes first";
    statusDisplay.FontSize = 24;
    statusDisplay.Name = "StatusDisplay"; // This is the name of the control
    statusDisplay.HorizontalAlignment = HorizontalAlignment.Center;
    statusDisplay.Margin = new Thickness(20);

    StackPanel layout = new StackPanel();
    layout.Children.Add(playingField);
    layout.Children.Add(statusDisplay);

    Content = layout;

    for (int i = 0; i < 9; i++)
    {
        Button currentButton = new Button();
        currentButton.Name = "Space" + i.ToString();
        currentButton.FontSize = 32;
        currentButton.Click += OnPlayLocationClick;

        playingField.Children.Add(currentButton);
    }

    game = new TicTacToe.GameCore();
}

void OnPlayLocationClick(object sender, RoutedEventArgs args)
{
    Button clickedButton = args.Source as Button;

    int iButtonNumber = Int32.Parse(clickedButton.Name.Substring(5,1));
    int iXPosition = iButtonNumber % 3,
        iYPosition = iButtonNumber / 3;

    if (game.MoveIsValid(iXPosition, iYPosition) && 
        game.Status() == TicTacToe.GameCore.GameStatus.StillGoing)
    {
        clickedButton.Content = 
            game.getCurrentPlayer() == TicTacToe.GameCore.Player.X ? "X" : "O";
        game.MakeMoveAndChangeTurns(iXPosition, iYPosition);

        // And this is where I'm getting it so I can use it.
        Label statusDisplay = FindName("StatusDisplay") as Label;
        statusDisplay.Content = "It is " +
            (game.getCurrentPlayer() == TicTacToe.GameCore.Player.X ? "X" : "O") +
            "'s turn";
    }
}



这是怎么回事吗?我在这两个地方使用相同的名称,但 FindName 无法找到它。我已经使用snoop,看层次试过了,但形式不应用可供选择的列表中显示出来。我搜索了计算器,发现我的应该能够使用VisualTreeHelper类,但我不知道如何使用它。

What's going on here? I'm using the same name in both places, but FindName can't find it. I've tried using Snoop to see the hierarchy, but the form doesn't show up in the list of applications to choose from. I searched on StackOverflow and found I should be able to use VisualTreeHelper class, but I don't understand how to use it.

任何想法?

推荐答案

FindName 运行在呼叫控制的XAML名称范围。在你的情况下,由于控制是完全在代码中创建,即XAML名称范围是空的 - 这就是为什么 FindName 失败。请参见此页面

FindName operates on the XAML namescope of the calling control. In your case, since the control is created entirely within code, that XAML namescope is empty -- and that's why FindName fails. See this page:

任何增加的元素树初始加载和处理后,必须调用相应的执行RegisterName用于定义XAML名称范围的类。否则,所添加的对象不能按照名称通过方法如FindName引用。仅仅设置Name属性(或X:名称属性)。不注册该名称到任何XAML名称范围

Any additions to the element tree after initial loading and processing must call the appropriate implementation of RegisterName for the class that defines the XAML namescope. Otherwise, the added object cannot be referenced by name through methods such as FindName. Merely setting a Name property (or x:Name Attribute) does not register that name into any XAML namescope.

要解决的最简单方法你的问题是在类的形式StatusDisplay标签的引用存储为私有成员。或者,如果你想学习如何使用VisualTreeHelper类,有一个代码片段在那走可视化树找到匹配的元素本页面的底部。

The easiest way to fix your problem is to store a reference to your StatusDisplay label in the class as a private member. Or, if you want to learn how to use the VisualTreeHelper class, there's a code snippet at the bottom of this page that walks the visual tree to find the matching element.

(编辑:当然,这是较少的工作叫 RegisterName 比使用VisualTreeHelper,如果你不不想将其存储到标签的参考。)

(Edited: Of course, it's less work to call RegisterName than to use the VisualTreeHelper, if you don't want to store a reference to the label.)

我建议你阅读了全部的第一个链接,如果您打算在任何深度使用WPF / Silverlight的。有用的信息有。

I'd recommend reading the first link in its entirety if you plan on using WPF/Silverlight in any depth. Useful information to have.

这篇关于FindName返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆