vb.net - 如何获取 PictureBox 中图像资源的名称?
问题描述
我正在开发一款游戏,它有一个放置系统,它几乎完成了,我正在尝试使用 My.Settings 制作一个保存系统,这是我到目前为止的代码
Private Sub Menu_Save_Click(sender As Object, e As EventArgs) Handles Menu_Save.Click
Dg_1 = MessageBox.Show("Are you sure you want to save? This will overwrite your previous save.", "Warning!", MessageBoxButtons.YesNo)
If (Dg_1) = DialogResult.Yes Then
If (Generated = 0) Then
Tb_Chat.Text += Environment.NewLine
Tb_Chat.Text += "Cannot save a blank world"
ElseIf Generated = 1 Then
My.Settings.savslot1_isused = True
My.Settings.savslot1_hearts = Hp
My.Settings.savslot1_hunger = Hunger
My.Settings.stg_slot01 = Pb_BlockSpace001.Image
My.Settings.stg_slot02 = Pb_BlockSpace002.Image
My.Settings.stg_slot03 = Pb_BlockSpace003.Image
My.Settings.stg_slot04 = Pb_BlockSpace004.Image
My.Settings.stg_slot05 = Pb_BlockSpace005.Image
Tb_Chat.Text += Environment.NewLine
Tb_Chat.Text += "World Saved. " + TimeOfDay + "."
Else
Exit Sub
End If
End If
End Sub
(我只保存了 5 个块来测试它)
那么它会出现一个错误说:
“图像”类型的值无法转换为“字符串”
我怎样才能使它获得资源的名称而不是尝试将图像转换为字符串???
解决方案
由于位图图像位于 My.Resources 中,请考虑以下内容。
首先如上所述,您可以在 PictureBox 的 Tag 属性中设置图像名称并在需要时检索它,或者使用PictureBox
带有属性的自定义(如果需要,更改名称)ResourceName 将存储资源名称。
Public Class ImageBox
Inherits PictureBox
''' <summary>
''' Name of resource in projects Resources
''' </summary>
''' <returns></returns>
Public Property ResourceName() As String
End Class
创建ImageResourceHelper.vb
并添加以下内容
Namespace My
<ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)>
Partial Friend Class _MyImages
Private ReadOnly MyProperties As Reflection.PropertyInfo()
Private ReadOnly MyBitmapNames As List(Of String)
Public BitMapImages As new Dictionary(Of String, Bitmap)
Public ReadOnly Property HasImages() As Boolean
get
Return BitMapImages.Count >0
End Get
End Property
Private Sub GetBitMapImages()
'BitMapImages = New Dictionary(Of String, Bitmap)
Dim propertyInfo As Reflection.PropertyInfo() =
GetType(Resources.Resources).GetProperties(Reflection.BindingFlags.NonPublic Or
Reflection.BindingFlags.Instance Or
Reflection.BindingFlags.Static)
Dim BitMaps = (From T In propertyInfo Where T.PropertyType Is GetType(Bitmap)).ToList
If BitMaps.Count > 0 Then
For Each pInfo As Reflection.PropertyInfo In BitMaps
BitMapImages.Add(
pInfo.Name.Replace("_", " "),
CType(Resources.ResourceManager.GetObject(pInfo.Name), Bitmap)
)
Next
End If
End Sub
Public Function BitmapFromResource(sender As String) As Bitmap
Dim Item = (
From propertyInfo In MyProperties
Where propertyInfo.PropertyType Is GetType(Bitmap) AndAlso propertyInfo.Name = sender
).FirstOrDefault
If Item IsNot Nothing Then
Return CType(Resources.ResourceManager.GetObject(Item.Name), Bitmap)
Else
Dim bm As New Bitmap(256, 256)
Dim gr As Graphics = Graphics.FromImage(bm)
gr.Clear(Color.Transparent)
Return bm
End If
End Function
Public ReadOnly Property BitmapNames As List(Of String)
Get
Return MyBitmapNames
End Get
End Property
Public Sub New()
MyProperties = GetType(Resources.Resources).
GetProperties(
Reflection.BindingFlags.NonPublic Or
Reflection.BindingFlags.Instance Or
Reflection.BindingFlags.Static)
MyBitmapNames = (
From propertyInfo In MyProperties
Where propertyInfo.PropertyType Is GetType(Bitmap)
Select propertyInfo.Name
).ToList
GetBitMapImages()
End Sub
End Class
<HideModuleName()>
Friend Module Resource_Images
Private ReadOnly instance As New ThreadSafeObjectProvider(Of _MyImages)
ReadOnly Property Images() As _MyImages
Get
Return instance.GetInstance()
End Get
End Property
End Module
End Namespace
表单设计器
- 添加一个按钮来设置图像(也可以在 ListBox 的选择更改或 BindingSource 的位置更改事件时完成。
- 添加另一个按钮以获取当前资源名称。
- 添加列表框
- 添加自定义图片框
我的设置
添加一个名为SelectedImageName
String 的新设置。
表格代码
以下代码使用资源名称加载 ListBox,确定是否SelectedImageName
设置,如果设置为 PictureBox 图像资源名称,如果未设置,则从资源中选择第一张图像。
On Form Closing 事件
如果通过检查 PictureBox ResourceName 属性设置图像,则设置SelectedImageName
将在 Form Shown 事件中拾取的资源是否仍然存在。
Imports System.ComponentModel
Public Class Form1
Private ReadOnly ImageBindingSource As New BindingSource
Private Sub SetImageButton_Click(sender As Object, e As EventArgs) Handles SetImageButton.Click
If ListBox1.SelectedItem Is Nothing Then
Exit Sub
End If
Dim current = CType(ListBox1.SelectedItem, KeyValuePair(Of String, Bitmap))
PictureBox1.Image = current.Value
PictureBox1.ResourceName = current.Key
End Sub
Private Sub GetImageNameButton_Click(sender As Object, e As EventArgs) Handles GetImageNameButton.Click
If Not String.IsNullOrWhiteSpace(PictureBox1.ResourceName) Then
MessageBox.Show(PictureBox1.ResourceName)
Else
MessageBox.Show("Set an image and try again")
End If
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
ImageBindingSource.DataSource = My.Images.BitMapImages
ListBox1.DataSource = ImageBindingSource
ListBox1.DisplayMember = "Key"
ListBox1.ValueMember = "Value"
If My.Images.HasImages Then
If Not String.IsNullOrWhiteSpace(My.Settings.SelectedImageName) Then
If My.Images.BitMapImages.ContainsKey(My.Settings.SelectedImageName) Then
PictureBox1.Image = My.Images.BitMapImages(My.Settings.SelectedImageName)
PictureBox1.ResourceName = My.Settings.SelectedImageName
ListBox1.SelectedIndex = ListBox1.FindString(My.Settings.SelectedImageName)
Else
PictureBox1.Image = My.Images.BitMapImages.First().Value
PictureBox1.ResourceName = My.Images.BitMapImages.First().Key
End If
End If
End If
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
If Not String.IsNullOrWhiteSpace(PictureBox1.ResourceName) Then
My.Settings.SelectedImageName = CType(ListBox1.SelectedItem, KeyValuePair(Of String, Bitmap)).Key
End If
End Sub
End Class
当然这是针对一个 PictureBox,对每个 PictureBox 重复。此外,如果一个或多个资源是图标,则需要相应地调整检索图像的代码。BitmapFromResource 方法也可用于按名称从资源中获取图像,如果未找到则返回空图像。
推荐阅读
- r - 在 R 中获取公历周数(类似于 Excel)
- mysql - Docker 提交实际上并没有提交
- python - 如何在单词之后和字符之前获取列表
- sql - 是否可以在 psql 中为表创建全局别名?
- azure-ad-b2c - Azure B2C - 基于电子邮件域的用户不同品牌
- c# - EventHub Azure 函数正确触发,但 EventData.Body 为 0 字节
- amazon-web-services - AWS Athena 错误:CREATE TABLE 上的 INTERNAL_ERROR_QUERY_ENGINE
- amazon-web-services - CloudFront 报告 apple-app-site-association(深度链接)的 5xx 错误,即使源服务器返回 HTTP 200
- c# - C# Mongodb 将 BsonDocument 类型列表反序列化为类类型列表
- c# - 在 Asp.Net Core 中实现是/否菜单的好方法是什么?