我想从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();
}
}
}
答案 0 :(得分:1)
如果我评论这两行,我没有错误
playArea.Children.Add(target);
playArea.Children.Add(Human);
不知何故,这两个已经在xaml的画布中...或者我不知道