【问题标题】:Dynamically Creating Image - Does not Exist in Current Context动态创建图像 - 当前上下文中不存在
【发布时间】:2013-05-02 18:07:01
【问题描述】:

我正在尝试在 C# 中的 WPF 中创建 WhackaMole 游戏。我有点菜鸟。在 for 循环中,我试图将“i”的数量添加到“图像”中。我收到以下错误:

 "Error The name 'Image1' does not exist in the current context" 

'Image2' 等也是如此。我正在尝试将图像集成到 StackPanel 中。

感谢您的帮助:)

    public partial class MainWindow : Window
    {
        Image[] ImageArray = new Image[50];
        public MainWindow()
        {
            Moleini = MoleScore[1];
            InitializeComponent();
            //string ImageName = "Image";
            for (int i = 0; i <= 8; i++)
            {
                Image Image = new Image();
                ImageArray[i] = Image;
                Image.Name = "Image" + i.ToString();
            }

            ////Create Images
            //for (int i = 0; i <= 8; i++)
            //{
            //    StackPanel1.Children.Add(CreateImage(i));
            //}

            //Dispacher for Mole to Appear
            System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = TimeSpan.FromSeconds(1);
            dispatcherTimer.Start();

            //Dispacher for Full Game Time
            System.Windows.Threading.DispatcherTimer endGame = new System.Windows.Threading.DispatcherTimer();
            endGame.Tick += new EventHandler(endGame_Tick);
            endGame.Interval = TimeSpan.FromSeconds(5);
            endGame.Start();
        }

        ////Create Image
        //public Image CreateImage(int i)
        //{

        //}

        private void dispatcherTimer_Tick(object sender, EventArgs e)
        {

            //Random Number Generator
            Random rnd = new Random();
            int num = rnd.Next(1, 9);

            //If Random Number is "1" Then Image will display
            if (num == 1)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                Image1.Source = MoleImage;            
            }
            //If Random Number does not equal 1
            if (num != 1)
            {
                ImageSource hole = new BitmapImage(new Uri(ImgHole));
                Image1.Source = hole;
            }

            //If Random Number is "2" Then Image will display
            if (num == 2)
            {
                ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                Image2.Source = MoleImage;
            }
}

【问题讨论】:

  • if (num == 2) 永远不会命中,因为你在 num != 1 之前检查,这将是 true 或 num==1
  • 我还有几个 if (num == x) 语句,这只是说使用生成的随机数显示其他图像。
  • 你的语义是错误的。你需要像 if(num == 1) { ... } else if(num == 2) { ... } 等那样做。
  • 谢谢,但这并不能解决我的问题:(
  • 什么是 ImageArray 以及在哪里/如何初始化它?

标签: c# image


【解决方案1】:

您是否考虑过在您的游戏中使用 MVVM 设计模式?它更适合 WPF 的技术,因为它将数据和 UI 层分开,就像 WPF 的 XAML 和 Binding 系统一样,它会让这变得更容易。

我记得answering 有一个关于扫雷游戏的类似问题,所以我从那里开始。

从创建Mole 对象开始。痣有 3 个属性:RowIndexColumnIndexIsUp 属性。

现在您需要一个模板来绘制您的Mole 对象。为local:Mole 对象创建一个DataTemplate,并使用您的图像绘制它。如果IsUp=True,则DataTrigger 可用于绘制痣图,如果IsUp=False,则可用于绘制孔图像。

现在在您的代码隐藏中,创建一个Mole 对象列表,并初始化它们的默认值。这只是意味着两个循环,通过创建Mole 对象,并设置它们的行/列索引。

要绘制列表,请在 XAML 中使用 ItemsControl。将ItemsControl.ItemsPanelTemplate 更改为Grid,并将ItemsControl.ItemContainerStyleGrid.RowGrid.Column 属性绑定到RowIndexColumnIndex 对象上的ColumnIndex 属性。

最后,启动一个计时器,随机将列表中带有IsUp=false 的随机Mole 对象的IsUp 属性更改为true。将其更改为 true 时,还启动第二个计时器,该计时器将在随机时间后更改 IsUp=false

添加分数应该相当容易。将ICommand HitMoleCommand 添加到Mole 对象,该对象返回RelayCommand,在IsUp=True 时启用,并在那里执行一些逻辑(计算积分、更改IsUp=False 和取消计时器等)。

但无论如何,Image1 不是您的 MainWindow 类的属性,这就是您无法从调度程序代码访问它的原因。仅创建一个对象并为其命名不会将其作为属性存储在 Window 上,就像在运行项目之前创建一个对象并在 XAML 中为其命名时一样。您需要将图像存储在类中的某个位置才能像这样访问它,例如在ImageArray 对象中。

我看到你在我写这篇文章的时间里找到了你的答案,但我还是把它发布了,因为我强烈认为如果你正在使用 WPF,你真的应该至少了解 MVVM 设计模式,即使您不选择使用它:)

【讨论】:

    【解决方案2】:

    除非您省略了代码,否则 Image1Image2 之前没有被声明过。在dispatcherTimer_Tick 范围内使用这些变量将导致编译时错误。

    我认为您打算改为引用 ImageArray

    // instead of this
    Image1.Source = MoleImage;
    // you want this
    ImageArray[1].Source = MoleImage;
    

    【讨论】:

      【解决方案3】:

      使用这个更新的代码:

                  private void dispatcherTimer_Tick(object sender, EventArgs e)
                  {
                      //Random Number Generator
                      Random rnd = new Random();
                      int num = rnd.Next(1, 9);
      
                      //If Random Number is "1" Then Image will display
                      if (num == 1)
                      {
                          ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                          ImageArray[1].Source = MoleImage;            
                      }
                      //If Random Number does not equal 1
                      if (num != 1)
                      {
                          ImageSource hole = new BitmapImage(new Uri(ImgHole));
                          ImageArray[1].Source = hole;
                      }
      
                      //If Random Number is "2" Then Image will display
                      if (num == 2)
                      {
                          ImageSource MoleImage = new BitmapImage(new Uri(ImgNameMole));
                          ImageArray[2].Source = MoleImage;
                      }
          }
      

      【讨论】:

      • 谢谢!终于成功了! :D
      【解决方案4】:

      Image Image = new Image(); 可能会导致问题。您应该考虑使用 Image image = new Image(); ,变量名上没有大写 I

      【讨论】:

      • 我们在C#中声明变量的方式绝对没有坏处,编译器可以正确区分。但从编码指南的角度来看,这不是最佳实践。
      猜你喜欢
      • 1970-01-01
      • 2018-09-25
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2019-08-05
      • 2020-07-31
      • 2021-01-16
      相关资源
      最近更新 更多