Head First C# - 第1章示例

时间:2017-02-19 08:27:59

标签: c#

我想从Head First C#中学习,但我在第一章中遇到了这个错误:

其他信息:指定的Visual已经是另一个Visual的子项或CompositionTarget的根。

我很确定代码与书中的完全相同,但我使用的是VS2015,示例是flr VS2013:

这是我的代码:

  

<Window x:Class="Save_the_humans.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Save_the_humans"
        mc:Ignorable="d"
        Title="Save the Humans" Height="700" Width="1000">
    <Window.Resources>
        <ControlTemplate x:Key="EnemyTemplate" TargetType="{x:Type ContentControl}">
            <Grid>
                <Ellipse Fill="#FFD61001" Height="100" Stroke="Black" Width="100"/>
            </Grid>
        </ControlTemplate>
    </Window.Resources>
    <Grid Background="Black">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="140"/>
            <ColumnDefinition/>
            <ColumnDefinition Width="160"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="150"/>
        </Grid.RowDefinitions>
        <Button x:Name="startButton" Content="Start!" HorizontalAlignment="Center"
                Grid.Row="1" VerticalAlignment="Center" Click="startButton_Click"/>
        <ProgressBar x:Name="progressBar" Grid.Column="1" Grid.Row="1" Height="20"/>
        <StackPanel Grid.Column="2" Orientation="Vertical" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox x:Name="AvoidThese"
                TextWrapping="Wrap" Text="Avoid These" FontSize="18" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" Background="Black"/>
            <ContentControl Content="ContentControl" HorizontalAlignment="Center" VerticalAlignment="Center" Template="{DynamicResource EnemyTemplate}"/>
        </StackPanel>
        <Canvas x:Name="playArea" Grid.ColumnSpan="3">
            <Canvas.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF0F259A" Offset="0.096"/>
                    <GradientStop Color="#FF25C714" Offset="1"/>
                </LinearGradientBrush>
            </Canvas.Background>
            <StackPanel x:Name="Human" Orientation="Vertical">
                <Ellipse Fill="White" Width="10" Height="10" Stroke="Black"/>
                <Rectangle Fill="White" Height="25" Width="10" Stroke="Black"/>
            </StackPanel>
            <TextBlock x:Name="gameOverText" Canvas.Left="210" TextWrapping="Wrap" Text="Game Over" Canvas.Top="195" Height="120" Width="535" FontFamily="Arial" FontSize="100" FontStyle="Italic" FontWeight="Bold"/>
            <Rectangle x:Name="target" Height="50" Canvas.Left="505" Stroke="Black" Canvas.Top="85" Width="50" RenderTransformOrigin="0.5,0.5">
                <Rectangle.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="45"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Rectangle.RenderTransform>
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFAE0E64" Offset="0.245"/>
                        <GradientStop Color="#FF170202" Offset="1"/>
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
        </Canvas>   
    </Grid>
</Window>
  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Threading;
namespace Save_the_humans
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Random random = new Random();
        DispatcherTimer enemyTimer = new DispatcherTimer();
        DispatcherTimer targetTimer = new DispatcherTimer();
        bool humanCaptured = false;
        public MainWindow()
        {
            InitializeComponent();

            enemyTimer.Tick += enemyTimer_Tick;
            enemyTimer.Interval = TimeSpan.FromSeconds(2);

            targetTimer.Tick += TargetTimer_Tick;
            targetTimer.Interval = TimeSpan.FromSeconds(.1);

        }

        private void TargetTimer_Tick(object sender, EventArgs e)
        {
            progressBar.Value += 1;
            if (progressBar.Value >= progressBar.Maximum)
                EndTheGame();

        }

        private void EndTheGame()
        {
            if(!playArea.Children.Contains(gameOverText))
            {
                enemyTimer.Stop();
                targetTimer.Stop();
                humanCaptured = false;
                startButton.Visibility = Visibility.Visible;
                playArea.Children.Add(gameOverText);
            }
        }

        private void enemyTimer_Tick(object sender, EventArgs e)
        {
            AddEnemy();
        }

        private void startButton_Click(object sender, RoutedEventArgs e)
        {
            StartGame();
        }

        private void StartGame()
        {
            Human.IsHitTestVisible = true;
            humanCaptured = false;
            progressBar.Value = 0;
            startButton.Visibility = Visibility.Collapsed;
            playArea.Children.Add(target);
            playArea.Children.Add(Human);
            enemyTimer.Start();
            targetTimer.Start();
        }

        private void AddEnemy()
        {
            ContentControl enemy = new ContentControl();
            enemy.Template = Resources["EnemyTemplate"] as ControlTemplate;
            AnimateEnemy(enemy, 0, playArea.ActualWidth - 100, "(Canvas.Left)");
            AnimateEnemy(enemy, random.Next((int)playArea.ActualHeight - 100),
                         random.Next((int)playArea.ActualHeight - 100), "(Canvas.Top)");
            playArea.Children.Add(enemy);

        }

        private void AnimateEnemy(ContentControl enemy, double from , double to , string propertyToAnimate)
        {
            Storyboard storyBoard = new Storyboard() { AutoReverse = true, RepeatBehavior = RepeatBehavior.Forever };
            DoubleAnimation animantion = new DoubleAnimation()
            {
                From = from,
                To = to,
                Duration = new Duration(TimeSpan.FromSeconds(random.Next(4, 6))),
            };
            Storyboard.SetTarget(animantion, enemy);
            Storyboard.SetTargetProperty(animantion, new PropertyPath(propertyToAnimate));
            storyBoard.Children.Add(animantion);
            storyBoard.Begin();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果我评论这两行,我没有错误

        playArea.Children.Add(target);
        playArea.Children.Add(Human);

不知何故,这两个已经在xaml的画布中...或者我不知道