winforms 在数据网格视图中选择行或单元格时,图片框不更新的问题

ddhy6vgd  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(138)

我正在建立一个交易卡的数据库,我用c# winforms做的前端显示datagridview很好,但是当选择不同卡片的单元格时(每张卡片是一行),它只加载第一行的图像,并在picturebox中只显示该图像,而忽略其他图像。我尝试了多种方法来更新控件,但收效甚微。
我所尝试的-dgv 1是datagridview,类似的代码被添加到鼠标悬停事件:

private void dgv_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
        {
            string setcode = (string)dgv1.Rows[e.Cell.RowIndex].Cells[1].Value;
            string cardname = (string)dgv1.Rows[e.Cell.RowIndex].Cells[5].Value;
            string imgpath = Path.Combine(Environment.CurrentDirectory, "pics", setcode, cardname + ".full.jpg");

            pictureBox1.Image?.Dispose();

            using (Image myImage = Image.FromFile(imgpath))
            {
                pictureBox1.Image = (Image)myImage.Clone();
                pictureBox1.Update();
            }

        }

这段代码似乎也不起作用:

pictureBox1.Image = Image.FromFile(imgpath); 
pictureBox1.Refresh();

我还尝试了其他方法,我发现,而搜索这个网站,并已只能显示1图像,之后的控制只显示该图像,没有其他人。
以youtube视频https://www.youtube.com/watch?v=hODwk8wJZGU的形式添加了额外的细节。注意,图像仍然没有改变。

relj7zay

relj7zay1#

您的帖子指出,当在DataGridView中选择行或单元格时,您希望能够用交易卡的图像更新PictureBox。您的最新评论表明,到目前为止,其他建议没有帮助。因此,与其试图从您的代码示例中诊断出什么不起作用,我可以提供的是一个示例,说明什么会起作用。
有时候,测试我们的编码假设更容易,方法是取一些“工作”的东西,并引入增量更改,直到它“崩溃”,所以我鼓励您使用我的最小示例并进行实验。
处理SelectionChanged事件是实现此结果的一种方法,由于我无法轻松获得***交易***纸牌图像的许可证,因此我将演示如何使用一个开源库***玩***纸牌。

图片来源Boardgame pack v2(知识共享许可证),作者:肯尼Vleugels。
数据绑定

jmcilhinney的精彩评论建议使用数据绑定。那么你到底要怎么做呢?基本上,你要创建一个类来表示一行数据,例如:

enum Value { Joker, Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Back }
enum Suit { Clubs, Diamonds, Hearts, Spades, }
class Card
{
    // Internal set makes the cell read only
    public Value Value { get; internal set; }
    public Suit Suit { get; internal set; }
}

然后创建一个BindingList<Card>,并在加载主窗体类的方法中将其赋给DataGridView的DataSource属性。

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        _imageBase = $"{GetType().Namespace}.Images.boardgamePack_v2.PNG.Cards";
        pictureBoxCard.Image = getCardImage(Value.Back);
    }
    private readonly string _imageBase;
    BindingList<Card> Cards = new BindingList<Card>();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        dataGridViewCards.AllowUserToAddRows = false;
        dataGridViewCards.RowHeadersVisible = false;
        dataGridViewCards.DataSource = Cards;

        #region F O R M A T    C O L U M N S
        Cards.Add(new Card()); // <- Auto generate columns
        dataGridViewCards.Columns["Value"].AutoSizeMode= DataGridViewAutoSizeColumnMode.Fill;
        dataGridViewCards.Columns["Suit"].AutoSizeMode= DataGridViewAutoSizeColumnMode.Fill;
        Cards.Clear();
        #endregion F O R M A T    C O L U M N S

        // Add a few cards
        Cards.Add(new Card { Value = Value.Ten, Suit = Suit.Diamonds });
        Cards.Add(new Card { Value = Value.Jack, Suit = Suit.Clubs });
        Cards.Add(new Card { Value = Value.Queen, Suit = Suit.Hearts });
        Cards.Add(new Card { Value = Value.King, Suit = Suit.Spades });
        Cards.Add(new Card { Value = Value.Ace, Suit = Suit.Diamonds });

        // Subscribe to the event that occurs when selection changes.
        dataGridViewCards.ClearSelection();
        dataGridViewCards.SelectionChanged += onSelectionChanged;
    }
    .
    .
    .
}

如上所示,数据绑定允许您通过操作Cards集合中的数据来向DGV添加卡和从DGV中移除卡,而不必直接使用UI控件。

处理事件

private void onSelectionChanged(object? sender, EventArgs e)
    {
        if (dataGridViewCards.CurrentCell == null)
        {
            pictureBoxCard.Image = getCardImage(Value.Back);
        }
        else
        {
            int row = dataGridViewCards.CurrentCell.RowIndex;
            if((row != -1) && (row < Cards.Count)) 
            {
                Card card = Cards[row];
                pictureBoxCard.Image = getCardImage(card);
            }
        }
    }

加载图像

您还需要一种可靠的方法来定位和加载图像,一种好方法是将图像的Build Action属性设置为Embedded resource

现在可以根据牌的值和花色检索图像。

BindingList<Card> Cards = new BindingList<Card>();
private Image getCardImage(Value value = Value.Joker, Suit? suit = null)
{
    switch (value)
    {
        case Value.Ace:
            return localImageFromResourceName($"{_imageBase}.card{suit}A.png");
        case Value.Jack:
            return localImageFromResourceName($"{_imageBase}.card{suit}J.png");
        case Value.Queen:
            return localImageFromResourceName($"{_imageBase}.card{suit}Q.png");
        case Value.King:
            return localImageFromResourceName($"{_imageBase}.card{suit}K.png");
        case Value.Joker:
            return localImageFromResourceName($"{_imageBase}.cardJoker.png");
        case Value.Back:
            return localImageFromResourceName($"{_imageBase}.cardBack_green3.png");
        default:
            return localImageFromResourceName($"{_imageBase}.card{suit}{(int)value}.png");
    }
    Image localImageFromResourceName(string resource)
    {
        using (var stream = GetType().Assembly.GetManifestResourceStream(resource)!)
        {
            return new Bitmap(stream);
        }
    }
}
private Image getCardImage(Card card) => getCardImage(card.Value, card.Suit);

相关问题