简体   繁体   English

WPF应用程序访问控制的代码隐藏

[英]WPF application access controls in code-behind

I'm workin on a WPF scorekeeping app. 我正在使用WPF计分应用程序。 So far the UI is done, but I can't access any of the controls in the code-behind. 到目前为止,UI已经完成,但是我无法访问后面代码中的任何控件。 Here's the XAML: 这是XAML:

<Window x:Class="Scoreboard.MainScoreBoard"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DartsLeague" Height="720" Width="1280">
    <Grid x:Name="MainGrid" Background="DarkGreen">
        <StackPanel x:Name="Player1" HorizontalAlignment="Left" VerticalAlignment="Stretch">
            <Label x:Name="Player1Name" Style="{StaticResource PlayerName}"/>
            <Label x:Name="Player1Score"  Style="{StaticResource Score}"/>
            <ScrollViewer x:Name="Player1Throws" Height="380" FlowDirection="RightToLeft">

            </ScrollViewer>
        </StackPanel>
        <StackPanel x:Name="Player2" HorizontalAlignment="Right" VerticalAlignment="Stretch">
            <Label x:Name="Player2Name" Style="{StaticResource PlayerName}">Player 2</Label>
            <Label x:Name="Player2Score" Style="{StaticResource Score}">501</Label>
            <ScrollViewer x:Name="Player2Throws" Height="380">

            </ScrollViewer>
        </StackPanel>
        <StackPanel x:Name="Input" HorizontalAlignment="Center"  VerticalAlignment="Top">
            <TextBox x:Name="CurrentNumber" MaxLength="3" Width="160" Margin="20" FontSize="30" TextChanged="TextBox_TextChanged"></TextBox>
            <Button x:Name="SubmitButton" IsDefault="True" Style="{StaticResource Golden} " Click="Button_Click">Запиши резултат</Button>
            <Button x:Name="CancelButton" Style="{StaticResource Golden}">Върни назад</Button>
        </StackPanel>
        <Grid x:Name="StatsGrid" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="60" Width="560">
            <StackPanel x:Name="Player1Stats" HorizontalAlignment="Left" VerticalAlignment="Stretch">
                <Label x:Name="Player1Legs" Style="{StaticResource BoardStats}"/>
                <Label x:Name="Player1Sets" Style="{StaticResource BoardStats}"/>
                <Label x:Name="Player1Avr" Style="{StaticResource BoardStats}"/>
            </StackPanel>
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Stretch">
                <Label Style="{StaticResource BoardStats}">LEGS</Label>
                <Label Style="{StaticResource BoardStats}">SETS</Label>
                <Label Style="{StaticResource BoardStats}">3 DART AVERAGE</Label>
            </StackPanel>
            <StackPanel x:Name="Player2Stats" HorizontalAlignment="Right" VerticalAlignment="Stretch">
                <Label x:Name="Player2Legs" Style="{StaticResource BoardStats}"/>
                <Label x:Name="Player2Sets" Style="{StaticResource BoardStats}"/>
                <Label x:Name="Player2Avr" Style="{StaticResource BoardStats}"/>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

App.xaml: App.xaml:

<Application x:Class="Scoreboard.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Scoreboard"
             StartupUri="StartWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <Style x:Key="Golden" TargetType="Button">
                <Setter Property="Background" Value="Gold" />
                <Setter Property="BorderBrush" Value="Black" />
                <Setter Property="Margin" Value="10" />
                <Setter Property="Padding" Value="4" />
                <Setter Property="FontSize" Value="30" />
            </Style>

            <Style x:Key="PlayerName" TargetType="Label">
                <Setter Property="Background" Value="White" />
                <Setter Property="Margin" Value="10"/>
                <Setter Property="FontSize" Value="34" />
                <Setter Property="BorderBrush" Value="Black" />
                <Setter Property="BorderThickness" Value="2" />
                <Setter Property="HorizontalContentAlignment" Value="Center" />
            </Style>

            <Style x:Key="Score" TargetType="Label">
                <Setter Property="Margin" Value="10" />
                <Setter Property="Background" Value="White" />
                <Setter Property="FontSize" Value="160" />
                <Setter Property="BorderBrush" Value="Black" />
                <Setter Property="BorderThickness" Value="2" />
                <Setter Property="HorizontalContentAlignment" Value="Center" />
            </Style>

            <Style x:Key="BoardStats" TargetType="Label">
                <Setter Property="Background" Value="Beige" />
                <Setter Property="Margin" Value="4" />
                <Setter Property="BorderBrush" Value="DarkRed" />
                <Setter Property="BorderThickness" Value="4" />
                <Setter Property="HorizontalContentAlignment" Value="Center" />
                <Setter Property="FontSize" Value="26" />
                <Setter Property="Padding" Value="8" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Heres the C# Code, It probably has more bugs that I know of, but it won't compile because it doesn't recognize any of the names from the XAML: 这是C#代码,我可能知道有更多错误,但是由于无法识别XAML中的任何名称,因此无法编译:

namespace Scoreboard
{
     public partial class MainScoreBoard : Window
{
    public MainScoreBoard()
    {
        InitializeComponent();
    }

    static bool IsTextAllowed(string text, int num)
    {
        Regex regex = new Regex("[^0-9.-]+");
        if (!regex.IsMatch(text))
        {
            num = Int32.Parse(text);
            return true;
        }
        else return false;
    }

    void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {

    }


    void Button_Click(object sender, RoutedEventArgs e)
    {
        // You should get in the habit of initializing your variables
        int currentScore = 0, currentPlayerScore, currentResult, legs, sets;
        bool Player1Turn = true;

        // You were getting null reference exceptions from attempting to access the Content property
        // without them ever getting set.  You can initialize them with default values in the xaml or in the
        // constructor on initialization (After InitializeComponent() call).
        if (Player1Score.Content != null && Player2Score.Content != null)
        {
            bool isGameOver = false;

            // This will loop infinitely if you don't fix the bugs in calculating the score, I put a comment on it as you are not getting a value for currentScore from anywhere
            while (Int32.Parse(Player1Score.Content.ToString()) != 0 || Int32.Parse(Player2Score.Content.ToString()) != 0)
            {
                if (IsTextAllowed(CurrentNumber.Text, currentScore))
                {
                    if (currentScore > 180)
                    {
                        MessageBox.Show("Написаното е над 180!!!");
                        continue;
                    }
                    if (Player1Turn)
                    {
                        Player1Turn = false;

                        currentPlayerScore = Int32.Parse(Player1Score.Content.ToString());

                        // The currentScore variable is never getting set, I initialized it for you but
                        // it needs to be assigned a value from somewhere otherwise it will always be
                        // currentResult = currentPlayerScore - 0
                        currentResult = currentPlayerScore - currentScore;
                        if (currentResult < 0)
                        {
                            MessageBox.Show("Предобри!!!");
                            continue;
                        }
                        else if (currentResult == 0)
                        {
                            MessageBox.Show("Game Over!!!");
                            legs = Int32.Parse(Player1Legs.Content.ToString());
                            legs++;
                            Player1Legs.Content = legs.ToString();
                            if (legs == 3)
                            {
                                //increas sets
                                //if sets == 3, end game and shut down app 
                            }
                            //Application.Current.Shutdown();                             

                            // Set flag so we do not keep looping through game over code
                            isGameOver = true;
                        }

                        Player1Score.Content = currentResult.ToString();

                        // Added this check here because I'm assuming you would want Player1Score to be reflected first
                        // before exiting the loop.
                        if (isGameOver)
                        {
                            // game is over, we do not want to keep showing the Game Over message box
                            break;
                        }
                    }
                    else
                    {
                        //the same for Player2
                        Player1Turn = true;
                    }
                }
            }
        }
    }
}
}

All of the controls have an x:Name on them, but I can access only 2 ot 3 of them, and even if I can, nothing happens. 所有控件上都有一个x:Name ,但是我只能访问其中的2个或3个,即使可以,也没有任何反应。 I want to write text in the textbox, and after some processing goes on with the textbox, some output and stats are supposed to show up on the labels, but it won't let me access any of it, or if it does, it's random, and nothing happens, as if there is no code there. 我想在文本框中写文本,在对文本框进行一些处理之后,应该在标签上显示一些输出和统计信息,但是它不允许我访问其中的任何一个,如果可以,则为随机的,没有任何反应,好像那里没有代码。

I cannot see the code for your Window declaration in the xaml. 我在xaml中看不到您的Window声明的代码。 But since you renamed the namespace and class, you should have this in your xaml window declaration. 但是,由于重命名了名称空间和类,因此应该在xaml窗口声明中使用它。

x:Class="Scoreboard.MainScoreBoard"

Essentially your xaml should look like this 基本上,您的xaml应该看起来像这样

<Window x:Class="Scoreboard.MainScoreBoard"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">       

</Window>

You do have a lot more bugs in the code behind as you need to call .ToString() in several places as well as some null reference exceptions, but if you get stuck in there you can always post a new question. 您确实需要在后面的代码中包含许多错误,因为您需要在多个位置调用.ToString()以及一些空引用异常,但是如果您陷入其中,则始终可以发布一个新问题。

public partial class MainScoreBoard : Window
{
    public MainScoreBoard()
    {
        InitializeComponent();
    }

    static bool IsTextAllowed(string text, int num)
    {
        Regex regex = new Regex("[^0-9.-]+");
        if (!regex.IsMatch(text))
        {
            num = Int32.Parse(text);
            return true;
        }
        else return false;
    }

    void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {

    }


    void Button_Click(object sender, RoutedEventArgs e)
    {
        // You should get in the habit of initializing your variables
        int currentScore = 0, currentPlayerScore, currentResult, legs, sets;
        bool Player1Turn = true;

        // You were getting null reference exceptions from attempting to access the Content property
        // without them ever getting set.  You can initialize them with default values in the xaml or in the
        // constructor on initialization (After InitializeComponent() call).
        if (Player1Score.Content != null && Player2Score.Content != null)
        {
            bool isGameOver = false;

            // This will loop infinitely if you don't fix the bugs in calculating the score, I put a comment on it as you are not getting a value for currentScore from anywhere
            while (Int32.Parse(Player1Score.Content.ToString()) != 0 || Int32.Parse(Player2Score.Content.ToString()) != 0)
            {
                if (IsTextAllowed(CurrentNumber.Text, currentScore))
                {
                    if (currentScore > 180)
                    {
                        MessageBox.Show("Написаното е над 180!!!");
                        continue;
                    }
                    if (Player1Turn)
                    {
                        Player1Turn = false;

                        currentPlayerScore = Int32.Parse(Player1Score.Content.ToString());

                        // The currentScore variable is never getting set, I initialized it for you but
                        // it needs to be assigned a value from somewhere otherwise it will always be
                        // currentResult = currentPlayerScore - 0
                        currentResult = currentPlayerScore - currentScore;
                        if (currentResult < 0)
                        {
                            MessageBox.Show("Предобри!!!");
                            continue;
                        }
                        else if (currentResult == 0)
                        {
                            MessageBox.Show("Game Over!!!");                                
                            legs = Int32.Parse(Player1Legs.Content.ToString());
                            legs++;
                            Player1Legs.Content = legs.ToString();
                            if (legs == 3)
                            {
                                //increas sets
                                //if sets == 3, end game and shut down app 
                            }
                            //Application.Current.Shutdown();                             

                            // Set flag so we do not keep looping through game over code
                            isGameOver = true;
                        }

                        Player1Score.Content = currentResult.ToString();

                        // Added this check here because I'm assuming you would want Player1Score to be reflected first
                        // before exiting the loop.
                        if (isGameOver)
                        {
                            // game is over, we do not want to keep showing the Game Over message box
                            break;
                        }
                    }
                    else
                    {
                        //the same for Player2
                        Player1Turn = true;
                    }
                }
            }               
        }
    }
}

Those styles in the xaml are not defined anywhere you should remove them until you implement the styles. 在实现样式之前,xaml中的那些样式在应删除它们的任何地方都没有定义。 I removed them when compiling as they are not defined. 我在编译时删除了它们,因为它们没有定义。

<Window x:Class="Scoreboard.MainScoreBoard"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Scoreboard"
    Title="DartsLeague" Height="720" Width="1280">
<Grid x:Name="MainGrid" Background="DarkGreen">
    <StackPanel x:Name="Player1" HorizontalAlignment="Left" VerticalAlignment="Stretch">
        <Label x:Name="Player1Name"/>
        <Label x:Name="Player1Score">501</Label>
        <ScrollViewer x:Name="Player1Throws" Height="380" FlowDirection="RightToLeft">

        </ScrollViewer>
    </StackPanel>
    <StackPanel x:Name="Player2" HorizontalAlignment="Right" VerticalAlignment="Stretch">
        <Label x:Name="Player2Name">Player 2</Label>
        <Label x:Name="Player2Score">501</Label>
        <ScrollViewer x:Name="Player2Throws" Height="380">

        </ScrollViewer>
    </StackPanel>
    <StackPanel x:Name="Input" HorizontalAlignment="Center"  VerticalAlignment="Top">
        <TextBox x:Name="CurrentNumber" MaxLength="3" Width="160" Margin="20" FontSize="30" TextChanged="TextBox_TextChanged"></TextBox>
        <Button x:Name="SubmitButton" IsDefault="True" Click="Button_Click">Запиши резултат</Button>
        <Button x:Name="CancelButton">Върни назад</Button>
    </StackPanel>
    <Grid x:Name="StatsGrid" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="60" Width="560">
        <StackPanel x:Name="Player1Stats" HorizontalAlignment="Left" VerticalAlignment="Stretch">
            <Label x:Name="Player1Legs">0</Label>
            <Label x:Name="Player1Sets" />
            <Label x:Name="Player1Avr" />
        </StackPanel>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Stretch">
            <Label>LEGS</Label>
            <Label>SETS</Label>
            <Label>3 DART AVERAGE</Label>
        </StackPanel>
        <StackPanel x:Name="Player2Stats" HorizontalAlignment="Right" VerticalAlignment="Stretch">
            <Label x:Name="Player2Legs"/>
            <Label x:Name="Player2Sets"/>
            <Label x:Name="Player2Avr" />
        </StackPanel>
    </Grid>
</Grid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM