Komponent usercontrol i jak dobrać się do jego własciwosci ?

0

Witam ponownie :)

Musiałem zrobić nowy temat by nie było zamieszania w poprzednim moim temacie, który lekko ewaluował :-D

Tak więc zrobiłem własny komponent, który składa się z 3 standardowych komponentów, mój komponent nazywa się:
CheckBoxTrackbal i składa się z Checkbox + TrackBal + Label.

oto kod tego komponentu:

 public partial class CheckBoxTrackBall : UserControl
    {
        public CheckBoxTrackBall()
        {
            InitializeComponent();
        }

        private void TBcheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (TBcheckBox.Checked == true) TBtrackbar.Enabled = true; else TBtrackbar.Enabled = false;
        }

        private void TBtrackbar_Scroll(object sender, EventArgs e)
        {
            TBlabel.Text = "Volume: " + TBtrackbar.Value;
        }
    }
 

Myślę, ze zasada działania tego komponentu nie wymaga wyjaśnień :-D

Teraz z czym mam problem:

  1. w moim komponencie, którego wkleję na formę jakoś nie działa zdarzenie scroll, czyli jak przesuwam trackballa to nie mogę obsłużyć zmian value w trackbalu.
  2. próbowałem obsłużyć zdarzenie MouseUP, ale to zdarzenie następuje tylko wtedy kiedy na moim komponencie zdarzenie wystąpi jedynie w miejscach gdzie nie ma włożonych w komponent moich 3 komponentów (czyli działa gdy kursor jest gdzieś na tle komponentu i nie nachodzi na komponenty tam osadzone)
  3. nie mogę w menu właściwości przypisać danych do TBcheckbox.text - mogę to zrobić przy form.load... tylko ze ja mam ponad 50 takich komponentów i nie wiem dlaczego nie wiem co zrobić bym mógł to zrobić w chwili wstawiania komponentu na formę w menu wlasciwisci po prostu brak właściwości TBcheckbox.text :-(

jak mam sobie z tym poradzić ?

0

Trzeba sobie napisać właściwości i zdarzenia masz przykład myślę że zrozumiesz:

Option Explicit On

Imports System.ComponentModel

Public Class UserControl1

    <Category("CheckBox"), Description(""), Browsable(True)>
    Public Property Checked As Boolean 'tak deklaruje sie wlasciwosci
        Get
            Return CheckBox1.Checked
        End Get
        Set(value As Boolean)
            CheckBox1.Checked = value
        End Set
    End Property

    <Category("CheckBox"), Description(""), Browsable(True)>
    Public Overrides Property Text As String 'nadpisuje niepotrzebna wlasciwosc Text User Control
        Get
            Return CheckBox1.Text
        End Get
        Set(value As String)
            CheckBox1.Text = value
        End Set
    End Property

    <Category("TrackBar"), Description(""), Browsable(True)>
    Public Property Value As Integer
        Get
            Return TrackBar1.Value
        End Get
        Set(value As Integer)
            TrackBar1.Value = value
        End Set
    End Property

    <Category("TrackBar"), Description(""), Browsable(True)>
    Public Event TrackBarScroll(sender As Object, e As EventArgs) 'deklaracja zdarzenia

    Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
        Label1.Text = "Volume: " & CStr(TrackBar1.Value) 'poprawna skladnia (mimo że VB pozwala na bzdury trzeba pisac poprawnie bo inaczej czasem kompilator może coś blędnie zinterpretowac i będziesz rok szukal błędu)
        RaiseEvent TrackBarScroll(sender, e) 'wywolanie zdarzenia
    End Sub

    Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
        TrackBar1.Enabled = CheckBox1.Checked 'skrócony zapis
    End Sub

    Private Sub CheckBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles CheckBox1.MouseUp, TrackBar1.MouseUp
        OnMouseUp(e) 'przekierowanie zdarzenia monz do wszyskich kontrolek przypisac to samo
    End Sub
End Class
0

autorze, dlaczego nie przerobisz sobie jakiegos kursu czy ksiazki dla poczatkujacych w c# i winforms? nie powinno ci to zajac wiecej niz pare dni a poczujesz sie duzo pewniej w srodowisku w ktorym pracujesz.

0

Dziękuję za przykład, ale chyba naprawdę jeszcze nie doszedłem do tego jak tworzyć własne komponenty i klasy a muszę w tym wypadku jakoś to zrobić :-(
patrząc na kod powyżej napisany przez kAzek to wszystko wygląda prosto.... widać dokładnie co gdzie i dlaczego ma być i jest to zrozumiałe.
Natomiast w ogóle nie wiem gdzie ja mam taki kod wpisać :-( (krótko mówiąc gubię się trochę w samym środowisku jak to początkujący).

Tak więc chcąc dodać własny komponent wchodzę do menu Project>Add User Control...
W okienku, które się pojawi wybieram ikonę "User Control" i nadaje nazwę nowego komponentu.
pojawia się nowa zakładka nazwa.Designer.cs i mogę sobie tutaj wstawiać to co mi potrzebne.
Natomiast w pliku nazwa.cs nie mogę dopisywać takich linijek kodu, więc w jakim pliku mam to dopisać bo nie mogę tego znaleźć :-(

@katelx na co dzień programuje w assemblerze .... robię to od około 20 lat, dla mnie języki wysokiego poziomu na co dzień nie były potrzebne.
Teraz tylko wystąpiła taka potrzeba i niestety 20 letnie programowanie w assemblerze nauczyło mnie innego myślenia odnośnie programowania. Teraz mam problemy z konwersjami danych (wcześniej operowałem tylko na bajtach, słowach itd.) operowałem na funkcjach arytmetycznych i boolowskich (na tyle ile mi pozwalały rozkazy danego procesora) . dla mnie języki wysokiego poziomu to abstrakcja, coś co ma ułatwiać programistom pisać programy tylko dlatego, ze nie potrafią ich napisać w języku procesora :-0).

Książki mam jest ich sporo, ale akurat nie C#.
Choć pewnie będę musiał cos kupić gdyż po napisaniu tej prostej aplikacji przyjdzie czas na napisanie dużo bardziej złożonej i najprawdopodobniej nie będzie pisana na forms.
To co teraz piszę to program diagnostyczny dla układu który stworzyłem i podłączam do PC za pomocą USB. Cały firmware pisany był w assemblerze, teraz musze to zsynchronizować z aplikacją pod Windows.

A to co muszę napisać w niedalekiej przyszłości ... to pełny edytor do pisania muzyki, który będzie wykorzystywał mój układ.
I chcę aby mniej więcej wyglądał tak jak na screnie w załączniku.
I wydaje mi się, ze stworzenie takiego interfejsu będzie nie lada wyczynem i na 100% będzie wymagała stworzenia własnych klas takich jak:
Lista paternów, okno paternów i samego paternu. dodatkowo dojdzie sama edycja dźwięku, gdzie mamy kilkanaście parametrów tworzenia kształtu fali.

0

Oczywiście że nie wiesz gdzie to wpisać bo to było w vb.NET (nie wiem dlaczego jakoś mi się skojarzyło że to w tym języku piszesz) dopiero teraz spojrzałem na zamieszczony przez Ciebie fragment kodu i widzę że to C# a więc to samo:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication38
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        [Category("CheckBox"), Description(""), Browsable(true)]
        public bool Checked
        {
            get { return checkBox1.Checked; }
            set { checkBox1.Checked = value; }
        }

        [Category("CheckBox"), Description(""), Browsable(true)]
        public override string Text
        {
            get { return checkBox1.Text; }
            set { checkBox1.Text = value; }
        }

        [Category("TrackBar"), Description(""), Browsable(true)]
        public int Value
        {
            get { return trackBar1.Value; }
            set { trackBar1.Value = value; }
        }

        public delegate void TrackBarScrollEvent(object sender, EventArgs e);
        [Category("TrackBar"), Description(""), Browsable(true)]
        public event TrackBarScrollEvent TrackBarScroll;

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label1.Text = "Volume: " + trackBar1.Value;
            this.TrackBarScroll(this, e);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            trackBar1.Enabled = checkBox1.Checked;
        }

        private void checkBox1_MouseUp(object sender, MouseEventArgs e)
        {
            OnMouseUp(e);
        }
    }
}
0

Wielkie dzięki o to mi chodziło :D
dodałem jeszcze trochę właściwości i zdarzeń - działa super :-D
Zauważyłem tylko jedną rzecz... mój komponent dziedziczy z groupbox w którym się znajduje właściwość fontow, która ustawiłem na bold.
Jak wyłączyć, aby komponent wewnątrz groupbox nie dziedziczył tej właściwości ... ustawienie bold = false nic mi nie daje w komponencie , którym zrobiłem :-(
I jak group box font.bold = true to mi robi labela i trackbara na bold (trackbara mi wydłuża)

0

A jednak cos nie tak :-( wiec podaruje sobie chyba ten komponent :-(
Objawy są takie.

mój komponent wygląda jak w załączniku wyżej. Po wklejeniu nawet żywcem kodu, który zamieścił kAzek i do dodaniu jednej linijki aby to wyglądało tak:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Sound_Control_V1._1
{
    public partial class CheckBoxTrackBar : UserControl
    {
        public CheckBoxTrackBar()
        {
            InitializeComponent();
        }
        [Category("CheckBox"), Description(""), Browsable(true)]
        public bool Checked
        {
            get { return checkBox1.Checked; }
            set { checkBox1.Checked = value; }
        }

        [Category("CheckBox"), Description(""), Browsable(true)]
        public override string Text
        {
            get { return checkBox1.Text; }
            set { checkBox1.Text = value; }
        }

        [Category("TrackBar"), Description(""), Browsable(true)]
        public int Value
        {
            get { return trackBar1.Value; }
            set { trackBar1.Value = value; }
        }

        public delegate void TrackBarScrollEvent(object sender, EventArgs e);
        [Category("TrackBar"), Description(""), Browsable(true)]
        
        public event TrackBarScrollEvent TrackBarScroll;

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            trackBar1.Enabled = checkBox1.Checked;
            this.TrackBarScroll(this, e);
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label1.Text = "Volume = " + trackBar1.Value;
            this.TrackBarScroll(this, e);

        }
 

objaw jest taki, ze:

a) działa zdarzenie "TrackBarScroll" gdy przełączam checkboxa i gdy przesuwam trackbara - czyli OK.

b) posiadam właściwość "text" w menu właściwości mojego komponentu CheckBoxTrackbar mogę zmienić właściwość CheckBoxTrackBar.text ale gdy kompiluję to wartość checkbox1.text wraca do wartości, która jest w samym komponencie checkbox1.text - wiec cos jest nie tak :-(

c) gdy komponent TrackBarScroll jest w groupbox w którym ustawiam font.bold = true to ta właściwość zmienia mi wszystkie komponenty mojego checkBoxTrackBar - a nie chcę by tak było :-(

d) ostatnia niedogodność jest taka, ze chce wywoływać zdarzenie gdy przesuwam trackbar i chce aby było również zdarzenie MouseUP i te dwa zdarzenia będę obsługiwał w formie głównej w zależności od jakiejś flagi - teraz to nie działa a właściwie to wywala błąd pewnie dlatego ze mamy dwa różne zdarzenia EventArgs i MouseEventArgs.

Powiem dlaczego chce obsługiwać dwa zdarzenia w trackbar. W zależności od jakiegoś ustawienia w programie chce mieć możliwość wysyłania nowej danej z wartości trackbar.value gdy zakończę przesuwanie trackbara (wtedy zdarzenie zarejestruje ostatnią zmianę wartości trackbar.value) lub każdą zmianę czyli jeżeli z wartości value=0 zmienię do wartości value=100 to nastąpi zdarzenie 100 razy - Teraz właśnie tak działa - a nie zawsze jest mi to na rękę.

Teraz pomyślałem, ze może warto by było dodać dodatkową właściwość, która będzie ustalać kiedy nastąpi zdarzenie ( czy jak zakończę przesuwanie czy podczas przesuwania)

powalczę jeszcze nad tym :-D... ale gdyby ktoś cos jeszcze doradził byłbym wdzięczny :-D

0

No to tak:
b) poprawione
c) nie bardzo rozumiem o co chodzi ale pewnie dziedziczą wszystkie właściwości po rodzicu
d) dodałem nowe zdarzenie TrackBarValueChanged które będzie wywoływane gdy zakończy się zmiana wartości trackbar (tylko raz a nie co wartość)

    public partial class UserControl1 : UserControl
    {

        private int lastTrackBarValue;

        public UserControl1()
        {
            InitializeComponent();
            lastTrackBarValue = trackBar1.Value; //nadaj warosc poczatkowa
        }

        [Category("CheckBox"), Description(""), Browsable(true)]
        public bool Checked
        {
            get { return checkBox1.Checked; }
            set { checkBox1.Checked = value; }
        }

        //tu trzeba bylo dodac atrybuty aby wartosc byla zapamietywana
        [Category("CheckBox"), Description(""), Browsable(true), Bindable(true)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public override string Text
        {
            get { return checkBox1.Text; }
            set { checkBox1.Text = value; }
        }

        [Category("TrackBar"), Description(""), Browsable(true)]
        public int Value
        {
            get { return trackBar1.Value; }
            set { trackBar1.Value = value; }
        }

        public delegate void TrackBarScrollEvent(object sender, EventArgs e);
        [Category("TrackBar"), Description(""), Browsable(true)]
        public event TrackBarScrollEvent TrackBarScroll;

        public delegate void TrackBarValueChangedEvent(object sender, EventArgs e, int Value);
        [Category("TrackBar"), Description(""), Browsable(true)]
        public event TrackBarValueChangedEvent TrackBarValueChanged; //to zdarzenie bedzie wywolywane jezeli zmieni sie wartosc trackbar


        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label1.Text = "Volume: " + trackBar1.Value;
            this.TrackBarScroll(this, e);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            trackBar1.Enabled = checkBox1.Checked;
        }

        private void checkBox1_MouseUp(object sender, MouseEventArgs e)
        {
            OnMouseUp(e);
        }

        private void trackBar1_MouseUp(object sender, MouseEventArgs e) 
        {
            if (lastTrackBarValue != trackBar1.Value) //czy wartosc trackbar sie zmienila
            {
                lastTrackBarValue = trackBar1.Value; //zapisz wartosc
                this.TrackBarValueChanged(this, e, lastTrackBarValue); //wywolaj zdarzenie
            }
        }

        private void UserControl1_Load(object sender, EventArgs e)
        {

        }
    }
0

Dziękuje @kAzek

Zrobiłem to trochę inaczej ..... wpisałem to i owo i wygląda to teraz tak:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OctaSID_Control_V1._1
{
    public partial class CheckBoxTrackBar : UserControl
    {
        public int lastTrackBarValue;
        private Boolean Step;

        public CheckBoxTrackBar()
        {
            InitializeComponent();
            lastTrackBarValue = trackBar1.Value; //nadaj warosc poczatkowa
            Step = false;
        }
        [Category("CheckBox"), Description(""), Browsable(true)]
        public bool Checked
        {
            get { return checkBox1.Checked; }
            set { checkBox1.Checked = value; }
        }

        [Category("CheckBox"), Description(""), Browsable(true)]
        public bool ValueStepByStep
        {
            get { return Step; }
            set { Step = value; }
        }

        [Category("CheckBox"), Description(""), Browsable(true), Bindable(true)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public override string Text
        {
            get { return checkBox1.Text; }
            set { checkBox1.Text = value; }
        }

        [Category("TrackBar"), Description(""), Browsable(true)]
        public int Value
        {
            get { return trackBar1.Value; }
            set { trackBar1.Value = value; }
        }

        public delegate void TrackBarValueChangedEvent(object sender, EventArgs e);
        [Category("TrackBar"), Description(""), Browsable(true)]
        
        public event TrackBarValueChangedEvent TrackBarValueChanged;

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label1.Text = "Volume = " + trackBar1.Value;

            if (Step == true)
            {
                lastTrackBarValue = trackBar1.Value;
                this.TrackBarValueChanged(this, e);
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked == true)
            {
                trackBar1.Enabled = true;
                if (trackBar1.Value != 0)
                {
                    lastTrackBarValue = trackBar1.Value;
                    TrackBarValueChanged(this, e);
                }
            }
            else
            {
                trackBar1.Enabled = false;
                if (trackBar1.Value != 0)
                {
                    lastTrackBarValue = 0;
                    TrackBarValueChanged(this, e);
                }
            }
        }

        private void trackBar1_MouseUp(object sender, MouseEventArgs e)
        {
            if (lastTrackBarValue != trackBar1.Value)
            {
                lastTrackBarValue = trackBar1.Value; 
                this.TrackBarValueChanged(this, e); 
            }
        }
    }
}

 

Najważniejsza cecha - to tylko jedno zdarzenie :-D (nie musze w aplikacji głównej obsługiwać dwóch różnych zdarzeń
druga cecha to właściwość boolean VolumeStepBystep - która ustala kiedy występuje zdarzenie:

  • każda zmiana trackbara,
  • ostatnia wartość trackbara.

a to ustalam w aplikacji.

c) nie bardzo rozumiem o co chodzi ale pewnie dziedziczą wszystkie właściwości po rodzicu

dokładnie dziedziczą a ja za Chiny nie mogę mojego komponentu zmusic by nie dziedziczył :-( to taki ostatni problem wizualny :-(

a tak ogólnie to wielkie dzięki :-D

0

Jesli w tym zmuszaniu komponentu, zeby nie dziedziczyl, chodzi Ci o ta sytuacje, ze przypisujesz jakis font do groupboxa, w ktorym jst Twoja kontrolka, i ten font "leci dalej", to mozesz po prostu w Twoim userControl zrobic overrida na setterze fonta (czy cokolwiek tam innego) i uzaleznic ustawianie fonta od jakiejs flagi - chodzi tutaj o wylapanie sytuacji, kiedy font sie ustala, bo leci z rodzica i wtedy po prostu go nie ustawiac

0

to mozesz po prostu w Twoim userControl zrobic overrida na setterze fonta (czy cokolwiek tam innego)

komponent checkbox i label ma właściwość font.bold ale trackbar nie ma nic takiego a go mi wydłuża. No i najzwyczajniej nie wiem jak to zrobić :-(

0

A moglbys tak w skrocie opisac co dokaldnie sie dzieje i przy jakim scenariuszu? :)

0

Mam groupbox w którym właściwość font.bold = true. Chce aby napis grupy był tłustym drukiem. Do tego groupboxa wklejam 8 x CheckBoxTrackBar (czyli mój komponent, który składa się z checkbox1, label1 i tracbar1.
Więc gdy wklejam mój komponent do tego groupboxa to właściwość checkbox.font.bold = true i label1.font.bold = true, a ja chce by było tak jak ustawiam w moim komponencie checkboxtrackbar. Inny dziwny objaw jest taki ze właściwość groupbox.font.bold wpływa również na trackbara, który jest w moim komponencie checkboxTrackBar i gdy jest ustawione bold=true to cały trackbar się wydłuża i nie mieści mi się cały na obszarze groupboxa (chowa się pod nim)
poniżej dwa screeny jak to wygląda w dwóch wypadkach.

0

Rozwiązałem ten problem "łopatologicznie" zlikwidowałem opis w groupbox.text i wstawiłem w to miejsce Label, który ma właściwość label.font.bold = true :-P
wiec można ominąć niektóre problemy - może droga okrężna , ale efekt końcowy taki jaki miał być :d)

1 użytkowników online, w tym zalogowanych: 0, gości: 1