Я пытаюсь создать форму, которая позволяет отображать/исчезать несколько изображений в зависимости от того, какие кнопки выбирает пользователь. Этот пример — просто тест, который я использую, чтобы попытаться понять это. Мой реальный проект сложнее, но применяются те же принципы, и у меня та же проблема.
У меня есть 5 прозрачных PNG, которые мне нужно наложить друг на друга, чтобы они отображались как одно изображение. Я поместил каждое из них в качестве фонового изображения панели, при этом для параметра backColor панели установлено значение прозрачности. В редакторе форм все выглядит хорошо, но изображения не отображаются должным образом, и я не знаю, почему.
Я просто хотел бы, чтобы кнопки либо включали, либо выключали видимость изображения в зависимости от его состояния.
Странно то, что все работает как надо, когда панели не уложены друг на друга. Но когда я складываю их, это действует.
Вот что у меня есть для всего:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PicA.Visible = False
PicB.Visible = False
PicC.Visible = False
PicD.Visible = False
End Sub
'Button All
Private Sub BtnAll_Click(sender As Object, e As EventArgs) Handles BtnAll.Click
If PicA.Visible = False Then
PicA.Visible = True
Else
PicA.Visible = False
End If
If PicB.Visible = False Then
PicB.Visible = True
Else
PicB.Visible = False
End If
If PicC.Visible = False Then
PicC.Visible = True
Else
PicC.Visible = False
End If
If PicD.Visible = False Then
PicD.Visible = True
Else
PicD.Visible = False
End If
End Sub
'Button A
Private Sub BtnA_Click(sender As Object, e As EventArgs) Handles BtnA.Click
If PicA.Visible = True Then
PicA.Visible = False
Else
PicA.Visible = True
End If
End Sub
'Button B
Private Sub BtnB_Click(sender As Object, e As EventArgs) Handles BtnB.Click
If PicB.Visible = True Then
PicB.Visible = False
Else
PicB.Visible = True
End If
End Sub
'Button C
Private Sub BtnC_Click(sender As Object, e As EventArgs) Handles BtnC.Click
If PicC.Visible = True Then
PicC.Visible = False
Else
PicC.Visible = True
End If
End Sub
'Button D
Private Sub BtnD_Click(sender As Object, e As EventArgs) Handles BtnD.Click
If PicD.Visible = True Then
PicD.Visible = False
Else
PicD.Visible = True
End If
End Sub
Вот короткий клип о том, что происходит, когда я запускаю форму: https://thewikihow.com/video_oG19RNJKjTU
Я просто больше запутываюсь, чем больше смотрю на это. Имеет ли значение порядок моего кода? имеет ли значение порядок укладки панелей?
Если кто-нибудь знает, что я делаю неправильно или если это невозможно, я был бы очень признателен.
Спасибо
Трюк с укладкой работает, только если они действительно сложены, как 1 является родителем 2, который является родителем 3, который является родителем 4, который является родителем 5. И в этом случае, когда вы делаете, скажем, 3 невидимыми , то 4 и 5 тоже будут невидимы.
Просто совет по кодированию; При переключении видимости используйте PicA.Visible = Not PicA.Visible
вместо If/Else.
Просто создайте один настраиваемый элемент управления с 5 слоями, включите/выключите слои и нарисуйте видимые элементы друг над другом.
Следующий код создает очень простой элемент управления слоями изображения. Каждый слой имеет свойства Visible и Image, и когда Visible каждого имеет значение True, он будет отображаться, в противном случае он не будет отображаться. Слои будут окрашены в порядке, обратном добавлению, поэтому последний добавленный слой будет сверху. После добавления или удаления слоев или изменения видимости сделайте элемент управления недействительным.
Вот код, который является хорошей отправной точкой. Вы можете расширить его позже и добавить поддержку автоматического обновления после изменения слоев, или добавить непрозрачность к слоям, или добавить режим размера (например, PictureBox) и многие другие свойства в зависимости от ваших требований.
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing.Design
Public Class Layer
Public Property Image As Image
Public Property Visible As Boolean = True
End Class
Public Class ImageLayersControl
Inherits Control
Sub New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
DoubleBuffered = True
ResizeRedraw = True
End Sub
<Editor(GetType(CollectionEditor), GetType(UITypeEditor))>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public Property Layers As Collection(Of Layer) = New Collection(Of Layer)
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
For Each l As Layer In Layers
If (l.Visible And l.Image IsNot Nothing) Then
e.Graphics.DrawImage(l.Image, 0, 0)
End If
Next
End Sub
End Class
Затем добавьте слои во время разработки или во время выполнения и сделайте слои видимыми или невидимыми во время разработки или с помощью кода, когда вам нужно:
Me.ImageLayersControl1.Layers(1).Visible = False
Me.ImageLayersControl1.Invalidate()
Примечание. Код требует, чтобы вы добавили ссылку на System.Design
или заменили атрибут редактора на <Editor("System.ComponentModel.Design.CollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor))>
.
Спасибо вам за ваши предложения. У меня пока нет опыта работы с пользовательскими элементами управления, но я постараюсь изучить их, чтобы правильно включить это.
Нет проблем, просто скопируйте код в свой проект, создайте проект, и вы увидите ImageLayersControl на панели инструментов. Затем поместите его экземпляр в форму и просмотрите его свойство Layers в браузере свойств. Добавьте слои и запустите приложение, чтобы увидеть результат! Довольно простой и расширяемый.
И обязательно прочитайте мой комментарий под вопросом ;)
Еще раз спасибо! Однако я столкнулся с 1 ошибкой. "Тип "CollectionEditor" не определен"
Обычно нажатие Ctrl + . Предложите правильное решение. Здесь правильным исправлением является добавление System.Design в качестве ссылки.
Или замените строку кода на <Editor("System.ComponentModel.Design.CollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", GetType(UITypeEditor))>
, которая не требует ссылки.
Все отлично работает! большое спасибо, что помогли мне. Я бы сам не догадался.
Без проблем! Создание такого пользовательского элемента управления — не единственное решение, но хорошее. В качестве альтернативы взгляните на этот пост Как сделать два прозрачных слоя с помощью c#?
На всякий случай, если вам интересно, я создавал инструмент для создания котировок оттенков для работы. Вот ссылка на видео окончательной работы. Еще раз спасибо youtu.be/PkwgYz0BZVQ
Рад видеть это, это было приятно! Спасибо, что поделился.
Просто создайте один настраиваемый элемент управления с 5 слоями, включите/выключите слои и нарисуйте видимые элементы друг над другом.