You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何代码无法将新增控件放置在TextBlock之外?

问题排查与修复

你的代码里Rect.Intersect判断不生效、MessageBox没触发,核心原因和修复方案如下:

主要问题点

  1. TextBlock的实际尺寸未正确计算
    在window_Loaded触发时,WPF的布局系统可能还没完成TextBlock的渲染,导致textBlock1.ActualWidth和textBlock1.ActualHeight都是0。这样生成的textblock_rect是个位置正确但尺寸为0的矩形,根本不可能和星星的矩形相交,判断条件自然永远不成立。

  2. 相交判断的写法不够可靠
    用Rect.Intersect返回的区域和Rect.Empty比较,可能会因为浮点数精度问题出现误判。直接用Rect.IntersectsWith()方法返回的布尔值判断相交,逻辑更直观也更可靠。

  3. 不必要的Canvas操作
    当前代码先把星星加到Canvas,判断相交后又移除,反复操作会浪费性能。应该先算好位置尺寸、确认不相交后再添加到Canvas。

修复步骤

1. 确保TextBlock获取正确尺寸

在获取TextBlock的尺寸前,强制触发它的布局计算。可以在window_Loaded里调用add_mini_star之前加这段代码:

// 强制TextBlock完成布局计算
textBlock1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
textBlock1.Arrange(new Rect(textBlock1.DesiredSize));

2. 替换相交判断逻辑

把原来的Rect.Intersect判断改成IntersectsWith:

// 替换原来的if条件
if (mini_star_rect.IntersectsWith(textblock_rect))
{
    MessageBox.Show("problem");
    ___Canvas1_.Children.Remove(mini_star);
    goto try_again;
}

3. 优化Canvas操作顺序

先计算星星的位置和尺寸,检查完相交后再添加到Canvas,避免反复添加移除:

try_again:
var star_size = rnd.Next(10, 40);
mini_star.Width = star_size;
mini_star.Height = star_size;

// 先计算位置
double left = rnd.Next(0, (int)(900 - star_size));
double top = rnd.Next(0, (int)(700 - star_size));

// 生成星星的矩形
Rect mini_star_rect = new Rect(left, top, star_size, star_size);

// 生成TextBlock的矩形(确保尺寸已正确计算)
Rect textblock_rect = new Rect(Canvas.GetLeft(textBlock1), Canvas.GetTop(textBlock1),
                            textBlock1.ActualWidth, textBlock1.ActualHeight);

// 判断相交
if (mini_star_rect.IntersectsWith(textblock_rect))
{
    MessageBox.Show("problem");
    goto try_again;
}

// 确认不相交后再添加到Canvas
Canvas.SetLeft(mini_star, left);
Canvas.SetTop(mini_star, top);
___Canvas1_.Children.Add(mini_star);
mini_star.Opacity = 0;
mini_stars.Add(mini_star);

完整修改后的关键代码

public void add_mini_star()
{
    System.Windows.Controls.Image mini_star = new System.Windows.Controls.Image();
    mini_star.Source = new BitmapImage(new Uri(@"/Star.png", UriKind.RelativeOrAbsolute));
    mini_star.Visibility = Visibility.Visible;

try_again:
    var star_size = rnd.Next(10, 40);
    mini_star.Width = star_size;
    mini_star.Height = star_size;

    double left = rnd.Next(0, (int)(900 - star_size));
    double top = rnd.Next(0, (int)(700 - star_size));

    Rect mini_star_rect = new Rect(left, top, star_size, star_size);

    // 确保TextBlock尺寸正确
    textBlock1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    textBlock1.Arrange(new Rect(textBlock1.DesiredSize));
    Rect textblock_rect = new Rect(Canvas.GetLeft(textBlock1), Canvas.GetTop(textBlock1),
                                textBlock1.ActualWidth, textBlock1.ActualHeight);

    if (mini_star_rect.IntersectsWith(textblock_rect))
    {
        MessageBox.Show("problem");
        goto try_again;
    }

    Canvas.SetLeft(mini_star, left);
    Canvas.SetTop(mini_star, top);
    ___Canvas1_.Children.Add(mini_star);
    mini_star.Opacity = 0;
    mini_stars.Add(mini_star);
}

private void window_Loaded(object sender, RoutedEventArgs e)
{
    sb1 = (Storyboard)FindResource("Storyboard1");

    // 提前初始化TextBlock布局
    textBlock1.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    textBlock1.Arrange(new Rect(textBlock1.DesiredSize));

    for (int x = 0; x < 32; x++)
    {
        add_mini_star();
    }

    DoubleAnimation[] start_anims = new DoubleAnimation[32];
    for (int x = 0; x < 32; x++)
    {
        start_anims[x] = new DoubleAnimation();
        start_anims[x].From = 0;
        start_anims[x].To = 1;
        start_anims[x].Duration = new TimeSpan(0, 0, 3);
        start_anims[x].BeginTime = new TimeSpan(0, 0, 4);
        start_anims[x].FillBehavior = FillBehavior.Stop;
        start_anims[x].Completed += OnCompleted;

        mini_stars[x].BeginAnimation(OpacityProperty, start_anims[x]);
    }

    sb1.Begin();
}

内容的提问来源于stack exchange,提问作者ExCeed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:17:12