例如,我有一个玩家对象,上面有一套卡片。
player.card[0] = "diamonds";
player.card[1] = "clubs";
player.card[2] = "spades";
etc...
我还有4个隐藏的图片盒,里面有套房图片(pb_spades,pb_hearts m等)
和另外4个图片框(pb_playerCard1,pb_playerCard2等),我必须从隐藏的pb中分配一个图像,该图像对应于玩家对象的卡片套装。
THEREFOR
if ( player.card[0] == "diamonds" ) { pb_playerCard1.Image = pb_diamonds.Image; }
当然,使用IF完成所有操作需要相当长的时间......我能以某种方式使用变量值作为对象名称的一部分吗?
有点儿
for (int i = 1; i != 5; i++)
{
pb_playerCard+'i'.Image = pb_+'player.card[i+1]'.Image;
}
答案 0 :(得分:1)
创建一个包含所有属性的类Suite,如下所示:
class Suite {
public string Name { get; set; }
public Image Image { get; set; }
然后为每种颜色创建一个静态对象:
public static Diamonds = new Suite { Name = "Diamonds", Image = Resources.DiamondImage };
// ...
}
现在您可以使用Suite.Diamonds。
更好的是使用Flyweight pattern来避免静态字段。您使用Flyweight来实现Card类。
答案 1 :(得分:1)
首先,没有理由拥有隐藏的PictureBox控件,因此您可以使用它的Image属性来存储图像。只需创建图像对象。
您可以将图像存储在字典中,可按名称编制索引:
var cards = new Dictionary<string, Image>() {
{ "diamonds", Image.FromFile("diamonds.jpg") }
{ "clubs", Image.FromFile("clubs.jpg") }
//...
};
然后代替:
if ( player.card[0] == "diamonds" ) { pb_playerCard1.Image = pb_diamonds.Image; }
你会写:
pb_playerCard1.Image = images[player.card[0]];
这段代码仍然不是很好(任何时候你看到像foo1,foo2,foo3这样的变量,你应该把它们放在一个数组中,这样它们就可以用数字索引)。下一步可能是重构代码,所以你有类似的东西:
pb_playerCard[0].Image = images[player.card[0]];
或者:
pb_playerCard[0].Image = player.card[0].Image;
答案 2 :(得分:1)
我认为您不能将值用作控件名称的一部分。但是,人们可以使用一种控制。您将不得不更改图片框的许多声明和初始化并将它们放入数组中,但您将能够编写更具描述性和可读性的代码。
答案 3 :(得分:1)
再次感谢大家,我使用List来存储播放器对象的卡套件以及存储图像引用的字典。
Dictionary<CardType, System.Drawing.Image> newDeckImages = new Dictionary<CardType, System.Drawing.Image>();
...
newDeckImages.Add(CardType.Diamonds, pb_diamonds.Image);
newDeckImages.Add(CardType.Hearts, pb_hearts.Image);
newDeckImages.Add(CardType.Clubs, pb_clubs.Image);
newDeckImages.Add(CardType.Spades, pb_spades.Image);
...
private void showMyCards()
{
pb_termCard1.Image = newDeckImages[Terminator.cards[0]];
pb_termCard2.Image = newDeckImages[Terminator.cards[1]];
pb_termCard3.Image = newDeckImages[Terminator.cards[2]];
pb_termCard4.Image = newDeckImages[Terminator.cards[3]];
}
答案 4 :(得分:0)
不,不是你是怎么做的,虽然通过反射可以实现类似的事情,但你想要的更接近于只使用FindControl作为“pb_playerCard”部分和一个简单的类型字典Dictionary<CardSuitEnum, WhateverTheTypeOfImageIs>
,您可以使用pb_diamonds.Image等填充。
Apols,我不知道是什么类型的.Image持有并且不能费心去查找它:)
答案 5 :(得分:0)
主类Player和关联的枚举应该是这样的:
class Player
{
public Player(int n)
{
Cards = new List(n);
}
public IList Cards { get; private set; }
}
enum CardType
{
Diamond,
Club,
Spade,
Heart
}
另一种方法GetPictureBox()应该在winform分部类
中
public PictureBox GetPictureBox(string pictureBoxName)
{
if(this.Controls.ContainsKey(pictureBoxName))
{
Control control = this.Controls[pictureBoxName];
PictureBox pictureBox;
if ((pictureBox = control as PictureBox) != null)
{
return pictureBox;
}
}
return null;
}
使用播放器实例在课堂中使用此方法。
Player player = new Player(3);
player.Cards.Add(CardType.Diamond);
player.Cards.Add(CardType.Club);
player.Cards.Add(CardType.Spade);
Dictionary dictionary = new Dictionary();
dictionary.Add(CardType.Diamond, pb_diamonds);
dictionary.Add(CardType.Spade, pb_spades);
dictionary.Add(CardType.Club, pb_clubs);
dictionary.Add(CardType.Heart, pb_hearts);
最后分配给image属性,
for (int i = 1; i < 5; i++)
{
string playercardPictureBoxName = string.Concat("pb_playercard", i.ToString());
PictureBox pictureBox = this.GetPictureBox(playercardPictureBoxName);
if (pictureBox != null)
{
pictureBox.Image = dictionary[player.Cards[i - 1]].Image;
}
}