Laden...

Kann man einer TextBox oder allgemein Steuerelementen neue Attribute zuweisen?

Erstellt von Davidnh vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.217 Views
D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren
Kann man einer TextBox oder allgemein Steuerelementen neue Attribute zuweisen?

Hallo,

ich frage mich ob es möglich ist, TextBoxen oder auch generell Steuerelementen neue Attribute zuzuweisen, also der Klasse neue Eigenschaften zu geben. Hier ein kleines Beispiel, damit klarer wird was ich meine:

Ich möchte einer Textbox zwei zusätzliche Eigenschaften verpassen, die ich dann ganz einfach abfragen kann wenn mir das object zur Verfügung steht.

Beispiel:

TextBox_TextChanged(object sender, RoutedEventArgs e)
{
 int zusatzAttribut = (sender as Textbox).getZusatzAttribut();
}

Hintergrund für meine Frage ist, dass ich mehrere Textboxen habe, die sich alle sehr ähnlich verhalten sollen, jedoch jeweils einen eigenen minimalwert bzw. maximalwert für die Eingabe haben sollen.
Ich möchte ungern für jede Textbox eine eigene Funktion schreiben.

EDIT:
Geht so etwas vielleicht über Databinding, oder bezieht sich das beim beispiel der TextBox nur auf den Text?
Aktuell unterscheide ich die TextBoxen über switch case und deren Namen (also ganz ekelhaft). Vielleicht ist es ja auch doch die bessere Variante, für jede TextBox eigene EventArgs Funktionen zu haben? Vielleicht könnt ihr mir ja ein paar Denkanstöße/Tipps geben

LG 😃

16.806 Beiträge seit 2008
vor 3 Jahren

Man würde in dem Fall von der TextBox erben und eine eigene Klasse machen.
Dann einfach über zusätzliche Eigenschaften.

656 Beiträge seit 2008
vor 3 Jahren

Oder, nachdem wir hier im WPF-Unterforum sind, könnten dir möglicherweise auch Attached Properties weiterhelfen (je nachdem, was du vorhast; das kommt aus deinem Snippet nur schwer bis gar nicht raus)

W
955 Beiträge seit 2010
vor 3 Jahren

Was has du genau vor? Wenn man einen Zahlenwert angeben soll der sich nur in einem Bereich befinden soll kannst du ein entsprechendes Control verwenden -> NumericUpDown

187 Beiträge seit 2009
vor 3 Jahren

Oder man verwendet dafür die Tag-Eigenschaft.

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Danke für eure Antworten, ich werde mir diese gleich nochmal genauer angucken. Aber erst zur Frage was genau ich vor habe:

Es geht um Textboxen in die Temperaturwerte eingegeben werden sollen.
Die Eingaben sollen dabei nur eine Nachkommastelle haben dürfen. Das habe ich bereits realisiert. Bis hierhin war es ausreichend für alle Textboxen die selben Eventargs (z.B. TextChanged) zu nutzen.
Jetzt soll aber jede Textbox zusätzlich individuelle Eingabebeschränkungen bekommen definiert durch Minimal- und Maximalwerte. Da ich die Textboxen in den Eventargs-Funktionen (nennt man die überhaupt so? Ich glaube ihr wisst was ich meine) nicht mühselig durch ihren Namen unterscheiden möchte um dann individuell die Eingaben zu prüfen suche ich eine Alternativlösung.

656 Beiträge seit 2008
vor 3 Jahren

Vermutlich wärst du damit - wie witte bereits vorgeschlagen hat - mit einem anderen Control besser unterwegs, was für den Anwendungsfall gedacht ist (wie beispielsweise eben ein NumericUpDown Control) - das gibt es in diversen Control Suites wie beispielsweise dem WPF Toolkit, Infragistics, DevExpress usw.; oder falls wirklich nötig/gewünscht kannst du dir ein eigenes Control direkt im eigenen Projekt dafür schreiben.
Damit brauchst du auch keine Events (pro Eingabefeld), in denen du (pro Eingabefeld) unterscheiden musst; sondern du definierst auf dem Control selbst die Eigenschaften wie Min/Max oder Format und setzt sie dort, wo du im XAML das Control hinpackst.

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Das NumericUpDown klingt nach einer guten Lösung!
Da ich bereits mehrere pages mit Textboxen bestückt hab und der Rest auch soweit gut funktioniert, würde ich es trotzdem gerne erst anders versuchen. Aber falls es nicht klappt werde ich auf diese Alternative zurückgreifen, danke für den Hinweis 😃

Die Tag Eigenschaft klingt glaube ich nach dem was ich suche, wie genau würde ich mit Hilfe der Tag Eigenschaft einer Textbox beispielsweise einen integer zuweisen, den ich dann abfragen kann, wenn ich die Textbox als object übergeben bekomme?

Ah ich habs schon herausgefunden, das ist ja denkbar einfach. Danke! 😃
Edit: doch nicht so einfach, wenn man zwei Variablen anstatt nur einer braucht.
Geht das trotzdem mit der Tag Eigenschaft?

Wenn ich also beispielsweise sage:

public class Grenzwerte
    {
        public int max { get; set; }
        public int min { get; set; }
    }

Grenzwerte test = new Grenzwerte(){min = 1, max = 2};

TextBox_1.Tag = test;

Wie frage ich jetzt min ab?

LG

2.078 Beiträge seit 2012
vor 3 Jahren

Die Tag-Eigenschaft ist im Grunde nur für irgendwelches Zeug, die kannst Du wie jede andere Property nutzen. Ich bin allerdings ein großer Feind von den Tag-Properties...

Bei WPF sollte man außerdem nicht die Control-Properties zur Datenhaltung missbrauchen, dafür sind die ViewModels da, dort gibt's dann die Properties mit den eigentlichen Daten und die sind an die Properties der Controls gebunden.
Bei einem eigenen Control schreibt man erst dann eigene DependencyProperties, wenn man sie in der internen Control-Logik beachten möchte (was bei dir ja der Fall ist) und dann bindet man wiederum die ViewModel-Properties an diese eigenen Control-Properties.

Ich würde außerdem nicht "erst anders versuchen" versuchen, denn daraus wird meiner Erfahrung nach fast immer die am Ende dauerhafte Lösung. Das machst Du ein paar mal, räumst später nicht auf und irgendwann hast Du ein unwartbares Chaos - überspitzt dargestellt.
Wenn ein NumericUpDown deine Anforderungen erfüllt, würde ich das auch direkt nutzen. Wenn nicht, bau dir ein eigenes CustomControl und nutze das, in beiden Fällen ersparst dir damit langfristig Arbeit

Wenn es dir um das Interesse bzw. den Lerneffekt geht, kannst Du ein eigenes Control schreiben, passende DependencyProperties dazu und in den CodeBehind kommt deine Logik, die mit den Werten aus den neuen DependencyProperties arbeitet. In der Nutzung kannst Du diese DependencyProperties dann direkt setzen, oder DataBinden.
Oder (es geht ja um den Lerneffekt) Du schaust dir Behaviors an, das sind einfach ausgedrückt ausgelagerte CodeBehind-Klassen, damit könnte man dein Vorhaben an vorhandene TextBoxen dran hängen, ohne ein eigenes Control zu brauchen. Das würde ich in deinem Fall aber nicht produktiv so machen, dein Beispiel schreit nach NumericUpDown oder CustomControl 😃

PS:
Deinen Antworten bisher nach zu urteilen ist MVVM für dich kein Begriff?
Mit WPF kann man auch Ohne MVVM arbeiten, aber glaub mir: Das macht auf Dauer kein Spaß.
Die großen Vorteile kommen erst wirklich zum Tragen, wenn man zumindest die groben Züge von MVVM nutzt. Man muss sich ja nicht super genau an alle Regeln halten, macht auch nicht immer Sinn, aber wenigstens die Trennung zwischen View und ViewModel sollte klar sein.

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Custum Controls klingen interessant, das werde ich mir mal genauer anschauen!

MVVM sagt mir nichts, ich kenne allerdings auch WPF erst seit ein paar Wochen.
Ich arbeite gerade daran eine Visualisierung für eine SPS gesteuerte Haussteuerung damit zu bauen. Das ganze wird dann Teil meiner Bachelorarbeit (Ich studiere Elektrotechnik, Programmieren ist also auch nicht zu 100% meine Stärke).
Ich lerne am besten durch Ausprobieren, anstatt mich vorher lange in darüber zu belesen.
Hat natürlich den Nachteil, dass ich vieles erstmal falsch oder umständlich mache, da ich die richtigen Herangehensweisen noch nicht kenne. Nach und Nach steige ich aber hinter immer mehr Dinge was WPF angeht und je mehr Dinge ich herausfinde, desto mehr Spaß finde ich auch daran.

16.806 Beiträge seit 2008
vor 3 Jahren

Ich lerne am besten durch Ausprobieren, anstatt mich vorher lange in darüber zu belesen.

Ja, das hört man leider oft - und meistens endet das nicht gut, weil es in den modernen Technologien kaum noch möglich ist das Zeug wirklich anzuwenden, wenn man die Basis nicht versteht.
Die Leute landen dann oft hier im Forum 😉
Wir sehen das quasi tagtäglich, dass der Ansatz so nicht erfolgreich ist; im Berufsleben und in der Community.

MVVM sagt mir nichts, ich kenne allerdings auch WPF erst seit ein paar Wochen.

WPF ist auf die Verwendung von MVVM konzipiert.
Du kannst quasi ohne MVVM kein ordentliches WPF machen; wirst von Workaround zu Workaround stoplern.

[Artikel] MVVM und DataBinding

D
Davidnh Themenstarter:in
21 Beiträge seit 2020
vor 3 Jahren

Mit CustomControl habe ich es jetzt hinbekommen.
Danke nochmal für den Tipp!

public class TextBoxMinMax : TextBox
    {
        public static DependencyProperty Minimalwert;
        public static DependencyProperty Maximalwert;

        static TextBoxMinMax()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBoxMinMax),
                new FrameworkPropertyMetadata(typeof(TextBoxMinMax)));

            Minimalwert = DependencyProperty.Register("Minimalwert", typeof(int), typeof(TextBoxMinMax), new UIPropertyMetadata(null));
            Maximalwert = DependencyProperty.Register("Maximalwert", typeof(int), typeof(TextBoxMinMax), new UIPropertyMetadata(null));

        }

        [Description("Größter zugelassener Wert"), Category("Common Properties")]
        public int max
        {
            get { return (int)GetValue(Maximalwert); }
            set { SetValue(Maximalwert, value); }
        }

        [Description("Kleinster zugelassener Wert"), Category("Common Properties")]
        public int min
        {
            get { return (int)GetValue(Minimalwert); }
            set { SetValue(Minimalwert, value); }
        }
    }

Ich habe auch nicht alles einfach ausprobiert, sondern wenn ich etwas bestimmtes haben wollte, erstmal google gefragt und mir vor allem Beispiele angeschaut. Wenn ich nur über ein Thema lese ohne anzuwenden, vergesse ich den größten Teil schnell wieder oder verstehe es nicht richtig.

2.078 Beiträge seit 2012
vor 3 Jahren

In dem CustomControl fehlt dass Event-Handling, was Du vorher schon hattest.
Aktuell sind die Properties nur stumpfe Datenhaltung ohne Funktion - das sollte man wie gesagt nicht tun.

Außerdem solltest Du dir die Namen gut überlegen.
DependencyProperties heißen immer z.B. "MaxValueProperty", während die eigentliche Property dann nur "MaxValue" heißt, das musst Du dann auch in der Register-Methode angeben.
Außerdem gibst Du in den Metadata unter Anderem den Wert an - der Default von int sollte aber auch eine Zahl sein und kein null.
Für die DependencyProperties gibts auch ein Snippet - "propdp" war das glaube ich.

CustomControls sind nicht dafür da, irgendein bestehendes Control um ein paar Daten zu erweitern.
Die sind dafür da, um die Control-Funktionalitäten zu entwickeln, während das Layout per ControlTemplate von woanders kommt - oder um bestehende Controls um Funktionen zu erweitern, was Du eigentlich erreichen möchtest.

PS:

Ich lerne am besten durch Ausprobieren, anstatt mich vorher lange in darüber zu belesen.

Geht mir auch so, aber sowas würde ich nicht produktiv machen.
Für sowas lege ich mir dann ein Dummy-Projekt an, indem ich ausprobieren kann.
So ist die Gefahr, dass die Spielwiese produktiv bleibt, nicht mehr ganz so groß