Тестване на удари с нови UIElements

Създавам WPF-потребителска контрола, която трябва да провери дали новите UIElements не се припокриват с никакви съществуващи UIElements. Кодът по-долу работи добре, когато baseRectangle е добавен към canvas преди извикването на button1_Click, но ако правоъгълникът е добавен в метода button1_Click, hittest не работи.

<Window x:Class="WpfCollisionTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Canvas Height="246" HorizontalAlignment="Left" Margin="12,12,0,0" Name="canvas1" VerticalAlignment="Top" Width="479"></Canvas>
        <Button Content="Button" Height="35" HorizontalAlignment="Left" Margin="12,264,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>


 public MainWindow()
 { 
     InitializeComponent();
 }

 private void button1_Click(object sender, RoutedEventArgs e)
 {
     canvas1.Children.Clear();
     Rectangle rect = new Rectangle();
     rect.Width = 200;
     rect.Height = 200;
     rect.Fill = Brushes.Red;
     canvas1.Children.Add(rect);
     if (VisualTreeHelper.HitTest(canvas1, new Point(100, 100)) != null)
     {
         MessageBox.Show("Collision");
     }
 }

person Jargo    schedule 30.01.2012    source източник
comment
Контролата трябва да бъде изобразена, преди да можете да я тествате. Може би изпълнете своя тест за попадение с по-нисък приоритет на диспечера от Render   -  person Rachel    schedule 30.01.2012
comment
Проблемът с този подход е, че трябва да добавя десетки обекти, които изискват тестване на удари. Има ли някакъв начин да се направи ръчно тестване преди изобразяването? Трябва да направя най-добрите удари срещу куп TextBlocks, които имам в отделна колекция, ако това е някаква помощ.   -  person Jargo    schedule 30.01.2012
comment
Без да сте тествали това: опитайте да добавите canvas1.UpdateLayout(); точно преди вашия код за тестване на удари. Това е само предположение.   -  person Clemens    schedule 30.01.2012
comment
Благодаря ти Клеменс. Вашето решение проработи.   -  person Jargo    schedule 01.02.2012


Отговори (2)


Извикването на canvas1.UpdateLayout() преди най-успешния решава проблема.

person Jargo    schedule 01.02.2012

Опитайте да добавите това, след като добавите правоъгълника към платното:

canvas1.Children.Add(rect);
rect.LayoutUpdated += (s, args) =>
{
    if (VisualTreeHelper.HitTest(canvas1, new Point(100, 100)) != null)
    {
        MessageBox.Show("Collision");
    }
};

Разбира се, това ще бъде засегнато всеки път, когато оформлението на rect се актуализира... така че може да искате да премахнете манипулатора или да направите допълнителна проверка вътре в него.

person Paul Hoenecke    schedule 30.01.2012