Zugriff auf Controls in einem WPF-Window

  • WPF

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Zugriff auf Controls in einem WPF-Window

    Hallo,

    ich habe in einem WPF-Window ein TabControl mit 3 Tabs. Auf den Tabs habe ich ein Frame und die Source von dem Frame ist eine Page mit mehreren Controls auf die ich vom Code aus zugreifen will. Leider schaffe ich das auch nach dem try and error Prinzip nicht und einen passenden Beitreg dazu hab ich auch nicht gefunden. Ich habe das WPF mit Visual Studio 2012 prof. erstellt und alle Windows, Grids, Frames und Pages mit Namen versehen.
    Ich hoffe nun, dass mir hier jemand den entscheidenden Tip geben kann.

    Viele Grüße
    Dieter

    hdo schrieb:

    Leider schaffe ich das auch nach dem try and error Prinzip nicht
    Lol! Das denke ich mir - und ich kenne auch keinen, der das schaffen könnte (iwas muss faul sein an diesem Prinzip ;)).

    hdo schrieb:

    mehreren Controls auf die ich vom Code aus zugreifen will.
    Das tut man halt nicht in Wpf - vergiß die Idee, vom Code auf Controls zuzugreifen.

    hdo schrieb:

    hier jemand den entscheidenden Tip geben
    MVVM–Pattern (Josh Smiths Artikel)
    Naja @ErfinderDesRades
    MVVM ist sicher ganz toll und ich bin auch ein fan (und dass du ein fan davon bist muss hier eh keiner erwähnen^^) aber es kommt sich immer auf die Anwendung drauf an.
    MVVM ist nicht immer automatisch das Richtige. Der Threadersteller gibt uns leider nicht wirklich hilfreiche Informationen was er machen will und somit kann ich da auch nicht mehr als Vermutungen machen.
    Aber wenn du auf z.B. einen Button vom Codebehind zugreifen möchtest, dann musst du dem erst einen Namen geben. (x:Name="btnName" oder Name="btnName")
    Trotzdem wäre es gut, wenn du uns genauer sagen könntest was du machen willst denn zu 90% gehst du das Ganze komplett falsch an.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Hallo thefiloe,

    ich habe mir jetzt den ganzen Tag das MVVM angesehen. Ist ja ganz toll aber ich steig da nicht so richtig durch und wie Du schon vermutet hast ist dies füe meine Zwecke oversized :wacko:

    Also was ich tun will ist eigentlich ganz einfach. Das Programm kopiert einfach Dateien von Rechner A nach Rechner B. Bevor die Datei auf Rechner B geschrieben wird, wird diese in eine PDF gewandelt. Dies Programm habe ich mit VB6 vor Jahren entwickelt und es läuft seitdem im Dauerbetrieb. Damit jetzt bei einem Rechnerwechsel keine Programmänderung nötig ist habe ich die Parameter wie z.B. Quellrechnername, Verzeichnis von wo nach wo usw. in mehreren Textboxen hinterlegt. Die ganzen Parameter werden auch in die Registry geschrieben und beim Neustart wieder in die Textboxen geschrieben.

    Da ich zur Zeit dabei bin alle meine VB6 Programme nach VB.NET zu konvertieren wollte ich dies Prinzip beibehalten. Bei den anderen Programmen die ich bis jetzt konvertiert habe, hab ich es mit WindowsForms ohne Probleme lösen können. Da ich nun mit WPF angefangen habe und dies auch ganz toll finde will ich das ganze eben damit lösen und stehe eben vor dem Problem die Daten aus der Registry in die Textbox auf der jeweilige Page, welche in einem Frame auf einem Tab in der winMain liegt, zu schreiben. Die ganzen Steuerelemente hab ich mit Namen versehen.

    Jetzt hoffe ich, dass ich verstanden werde und Du kannst mir sagen wie ich das ganze am besten und einfachsten lösen kann. Würde mich sehr freuen :)
    Ich verstehe wo du hängst. Jedoch ist dies tatsächlich ein Anwendungsgebiet für MVVM. MVVM würde ich grundsätzlich immer Verwenden, da es auch nicht mehr Aufwand ist als ohne. Im Gegenteil es ist eher weniger. Ich verwende nur dann kein MVVM, wenn ich z.b. komplett neue Contols entwickle, da du dort mit MVVM nicht weit kommst. In deinem Fall geht das jedoch wunderbar.
    Erstelle ein ViewModel welches beim Start (z.B. im Konstruktor) deine Daten aus der Registry(besser wäre eine Xml-Datei o.a.) in Properties in deinem ViewModel lädt. Jetzt musst du nur noch deinem Fenster als DataContext eine Instanz von deinem ViewModel zuweisen und über Bindings an das ViewModel binden. Klingt nach viel, ist jedoch sehr wenig.
    Wenn du mir sagst wo genau du da hängst kann ich dir helfen.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    ich hänge am schreiben der Daten aus der Registry in die Textbox. Die Daten liegen mir als String vor nur wie bringe ich diese in die Textbox?
    Mit Deiner Beschreibung kann ich jetzt leider nicht so viel anfangen. Es geht schon bei erstellen eines ViewModel los. Wen Du mir dazu ein kleines Beispiel geben könntest. Auch für Deine weiteren Erklärungen wäre mir ein kleines Beispiel sehr nützlich. Ich hoffe ich verlange nicht zuviel.
    Naja weißt du in WPF hast du die Möglichkeit ohne ein einziges mal ein Control direkt anzusprechen diese zu steuern.
    Jedes Control hat einen DataContext. Dieser DataContext kann alles sein. In diesem Fall ein ViewModel. Das ist von mir aus das einzige mal, dass du ein Control ansprichst nämlich du setzt den DataContext des Controls. Nun kannst du in XAML Bindings machen und an bestimmte Propertise binden.
    Schau mal hier durch: msdn.microsoft.com/en-us/library/ms750612.aspx
    Wichtig ist dabei, dass deine ViewModel INotifyPRopertyChanged implementieren. Dies beinhaltet ein Event welches z.B. die TextBox benachrichtigt, dass sich der Wert welcher an die Text-Eigenschaft gebunden wurde geändert hat.
    Dazu würde ich einfach eine Basisklasse machen welche jedes ViewModel implementiert. Ich selbst programmiere kein VB.NET mehr und kanns auch eigentlich nicht mehr(zu ungewohnt). Aber kann dir ne ältere C# Klasse von mir geben, welche ich verwende seit ich mit WPF angefangen habe. Sie ist zwar nicht wirklich aktuell aber war immer zu faul sie zu aktualiesieren (nach dem Motto so lange es funktioniert :D):
    Spoiler anzeigen

    Du kannst sie in VB.NET konvertieren wenn du willst (einfach googeln)

    Quellcode

    1. [Serializable]
    2. public class PropertyChangedBase : INotifyPropertyChanged
    3. {
    4. [field:NonSerialized]
    5. public event PropertyChangedEventHandler PropertyChanged;
    6. public bool SetProperty<T>(T value, ref T field, Expression<Func<object>> property)
    7. {
    8. return SetProperty(value, ref field, GetPropertyName(property));
    9. }
    10. public bool SetProperty<T>(T value, ref T field, string property)
    11. {
    12. if (field == null || !field.Equals(value))
    13. {
    14. field = value;
    15. OnPropertyChanged(property);
    16. return true;
    17. }
    18. return false;
    19. }
    20. public void OnPropertyChanged(string propertyName)
    21. {
    22. if (PropertyChanged != null)
    23. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    24. }
    25. public void OnPropertyChanged(Expression<Func<object>> property)
    26. {
    27. OnPropertyChanged(GetPropertyName(property));
    28. }
    29. public string GetPropertyName(Expression<Func<object>> property)
    30. {
    31. var lambda = property as LambdaExpression;
    32. MemberExpression memberExpression;
    33. if (lambda.Body is UnaryExpression)
    34. {
    35. var unaryExpression = lambda.Body as UnaryExpression;
    36. memberExpression = unaryExpression.Operand as MemberExpression;
    37. }
    38. else
    39. {
    40. memberExpression = lambda.Body as MemberExpression;
    41. }
    42. var constantExpression = memberExpression.Expression as ConstantExpression;
    43. var propertyInfo = memberExpression.Member as PropertyInfo;
    44. return propertyInfo.Name;
    45. }
    46. }

    Oben kommt noch hin:

    Quellcode

    1. using System.ComponentModel;
    2. using System.Linq.Expressions;
    3. using System.Reflection;





    Im ViewModel würde dann z.B. deine Eigenschaft so aussehen:
    Ein Beispiel für ein sehr einfaches Viewmodel wäre:
    Spoiler anzeigen

    Quellcode

    1. public class MeinViewModel : PropertyChangedBase
    2. {
    3. //ctor
    4. public MeinViewModel()
    5. {
    6. MeinText = "Text"; //hier kannst du die werte aus der registry laden
    7. }
    8. string _meinText;
    9. public string MeinText
    10. {
    11. get { return _meinText ?? (_meinText = String.Empty); } //falls ?? nicht übersetzt werden kann: if(_meinText == null) _meinText = String.Empty; %neue zeile% return _meinText;
    12. set { SetProperty(value, ref _meinText, () => MeinText); }
    13. }
    14. }


    Den DataContext kannste dann über verschiedene Wege setzen. Ich denke der einfachste für dich ist:

    Alles was dann im Codebehind von deinem Fenster ist wäre z.B.:
    Spoiler anzeigen

    Quellcode

    1. public class MeinFenster : Window
    2. {
    3. //ctor
    4. public MeinFenster()
    5. {
    6. DataContext = new MeinViewModel();
    7. }
    8. //...
    9. }


    Und das XAML z.B.:

    XML-Quellcode

    1. <Window ...>
    2. <TextBox Text="{Binding MeinText, UpdateSourceTrigger="PropertyChanged"}"/>
    3. </Window>



    So zum Schluss jetzt nochmal vielmals entschuldigung aber ich habe gerade kein Visualstudio zur Verfügung und hab den Code im Windows Editor geschrieben. Wenn ich VB Code dort schreibe würde der zu 99,9% nicht funktionieren. Also sei mir bitte nicht böse und konvertiers einfach :)


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „thefiloe“ ()

    Edit by ErfinderDesRades: unnötiges Vollzitat entfernt

    Hallo thefiloe,
    hallo ErfinderDesRades,

    ich danke euch ganz herzlich für Eure Bemühung. Bin dabei die ganzen tut´s zu bearbeiten und hab mir auch 2 Bücher zum Thema zugelegt. Mittlerweile bin ich schon ein ganzes Stück weiter :thumbsup: und werde in Zukunft alle Projekte mit WPF erstellen oder alte konvertieren.
    Was mich noch interesieren würde ist warum Du thefiloe nicht mehr in VB programmierst, was sind die Vorteile von C# und wie schwer ist der Umstieg von VB auf C#?
    Meine Vorkenntnisse was C betrifft ist nur das klassische C nicht C++.

    LG
    Dieter

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Bin innerhalb von nem Nachmittag umgestiegen und hab mich sehr schnell dran gewöhnt. Liegt vll. auch dran, dass ich damals schon die Syntax recht gut von C++ kannte.
    Vorteile gibts meiner Meinung nach sehr viele. Hab die schon so oft aufgelistet, dass ich jetzt eig. keine Lust mehr dazu habe. Es fängt für mich mit Lesbarkeit an. Ich kann VB einfach nicht lesen. Die ganzen Endifs usw. sind einfach nervig. if meine if(true) ist doch einfach wesentlich einfacher wie If ... Then ... EndIf naja ist ansichtssache. Dann gehts weiter, dass ich öfters mal unsafe brauche und das gibt es in VB.NET einfach nicht was für mich nen rießen nachteil ist. Außerdem gibt es noch weitere Kleinigkeiten wie z.B. dass gewisse operatoren wie z.b. der ?? operator nicht vorhanden sind. Des weitern findet man wesentlich mehr Material in C# als in VB in Internet und die ganzen veralteten Teile wie MsgBox, Shell,... sind weg. Könnte noch weiter machen aber leider keine Zeit.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    och - naja - vb hat auch ein paar syntaktische Vorzüge gegenüber c#. Und der vb-ObjectBrowser ist besser.
    Und unsafe braucht man wirklich nur verdammt selten. Nicht mal inne Bildverarbeitung braucht mans wirklich - ich hab mal mit vb-Array-Operationen einen PixelFilter hinbekommen, der war kaum merklich langsamer als die c#-unsafe-Konkurrenz.
    aber insgesamt haste recht: die c#-Syntax ist bisserl schöner.

    Entscheidend für vb spricht, dasses ein vernünftiges Lehrbuch für umsonst gibt: dieses Buch lesen (hingegen das Galileio-Openbook ist Mist). Damit lernt man alles, was man über VisualStudio, OOP und Framework wissen muß - etwas vergleichbares für c# ist mir nicht bekannt.
    Wegen dieses Buches täte ich auch einem, der c# lernen will, empfehlen, mit vb anzufangen, und später umzusteigen. Wie du sagst: Wenn man vb kann, geht der Umstieg in wenigen Tagen, bzw. es ist kein Umstieg, sondern eine Erweiterung, denn man kann dann ja beliebig zw. den Sprachen hin- und her-switchen.
    Unsafe ist perfekt gerade bei großen Puffern. z.B. kannste dir damit oft Speicherkopieren ersparen was einfach Performance ohne ende frisst. ObjectBrowser? Das ist genau der Selbe? Das Buch... nunja das Buch finde ich mittelmäßig und was ich auch noch sagen kann ist, dass ich garantiert nie jemandem empfehlen würde eine Sprache zu lernen weil es dort nen Buch gibt. Es gibt für C# zig Bücher auf Deutsch und sicher über hundert auf Englisch. Dass sich jemand die paar € nicht leisten kann, kann ich mir kaum vorstellen. Btw. ich habe in meinem Leben keine Zeile aus einem C# noch einen VB Buch gelesen. Hab alles aus Foren, probieren und msdn genommen. Ich versteh genauso "Visual Studio, OOP und Framework". Bin allgemein der Meinung wenn man auf etwas selbst draufkommen muss, dann vergisst man das so gut wie gar nicht mehr. Wenn jedoch alles in nem Buch vorgekaut wird naja.

    In einem Punkt geb ich dir recht. Die Openbooks würde ich auch nicht lesen. Die sind scheiße und da ist auch schon der Grund wieso sie gratis sind :)


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    thefiloe schrieb:

    Das Buch... nunja das Buch finde ich mittelmäßig
    oh - dann kannst du sicherlich ein besseres empfehlen.

    Aber es sollte schon die in dieses Buch lesen (hingegen das Galileio-Openbook ist Mist) angesprochenen Themenbereiche abdecken, insbesondere
    Schon am Inhaltsverzeichnis fällt auf: Klaus Löffelmann fängt am richtigen Anfang an.
    z.B. ein Projekt mit dem Pflichtenheft (also, daß man nicht drauflos-proggt, sondern erstmal richtig kräftig Man-Power investiert in die Eruierung und Festlegung der Projekt-Ziele).
    Und dann geht er die IDE durch, und beleuchtet viele (alle ist wohl nicht möglich) Facetten, wie die IDE den Programmierer unterstützen kann.
    Das ist auch meine Meinung, nämlich das das das Wichtigste ist, und das Erste, was ein Einsteiger lernen sollte, und möglichst gründlich.
    Nach 2 Kapiteln, zugeschnitten auf Umsteiger von VB6, und von VB2003 steigter in OOP ein, und auch hier wieder am richtigen Anfang: Überlegungen zur Namensgebung und weiteren Programmier-Konventionen, die einen einheitlichen Stil gewährleisten, und damit Wartbarkeit (und "Teamfähigkeit").
    OOP – Vererbungslehre rauf und runter, Polymorphie, Ressourcenbereinigung, benutzerdefinierte Operatoren, Generika, Delegaten und Ereignisse, Auflistungen, Enumerationen, sogar Regex ( = mächtiges Instrument für Suchen/Ersetzen in Text ) machter durch!
    Dann kommt Windows.Forms, und wieder – sagte ich das schon, daß mir das ausgezeichnet gefällt? - fängter mit Grundsätzlichkeiten an, Überlegungen zu Datenhaltung, Validierung, Bedien-Ergonomie und dergleichen.
    ist dir tatsächlich ein ebenbürtiges Buch bekannt?
    Also dasses viele Bücher gibt, ist klar, und dass insbes. Bücher zu SpezialThemen ausgezeichnet sein mögen - nix dagegen, aber solche Bücher wären nicht vergleichbar.

    Gesucht ist ein Buch, was aus einem Voll-Noob einen passablen Programmierer machen kann.
    meine rede ist: Mir ist nur eines bekannt, was das kann.

    ich wäre recht froh, machte man mich mit weiteren derart kompetenten Büchern bekannt. Zum Beispiel empfiehlt Picoflop als Referenz gerne die VB-Sprachreferenz auf MSDN, und als Nachschlage-Werk ist das glaub super. Nur bis man hinter die Systematik gekommen ist...

    thefiloe schrieb:

    Du kannst mir nicht erzählen, dass es nur EIN buch gibt das was kann.

    Man sollte ggf bedenken, dass es wichtig ist, ob die SPRACHE des Buches entscheidend ist ;) Kann mir problemlos vorstellen, dass es auch sehr gute VB.Net Bücher auf ENGLISCH gibt - aber das ist halt nicht jedermanns Sache. Mein persönlicher Favorit: "CLR via C#" von Jeffrey Richter. Das ist a) englisch und b) C# aber es vermittelt wirklich ein tiefes Wissen über das Net Framework selbst. Ist halt nur nix für Anfänger ;)
    Wie EDR schon sagte: Für absolute Beginner empfehle ich die MSDN Einfürhung in VB. Die ist IMHO ziemlich gut und liefert alles, was ein LERNWILLIGER (new String("!"c, 1024)) Anfänger braucht.

    ErfinderDesRades schrieb:

    Gesucht ist ein Buch, was aus einem Voll-Noob einen passablen Programmierer machen kann.

    Das gibts halt eh nicht. Genausowenig wie es das perfekte Werkzeug gibt, das gleichzeitig schleift, bohrt und sägt.
    naja, doch, glaubich wenigstens. Wenn man die in post#13 angesprochenen Themen in dem Buch nachgelesen und verstanden hat, ich denke, dann muss einem iwas noch ganz anneres fehlen, wenn einen das nicht zu einem passablen Programmierer entwickelt hat.

    btw: ich hab die letzten Tage mit Fleiß nach einer Doku zur Array-Klasse gesucht, also v.a. die Array-Initialisierer. Fand ich per Google was in der 2012er Sprach-Referenz, aber nicht bei der SprachReferenz, sondern bei den Sprach-Features im Programmier-Handbuch.
    Und dann erst fund ich, dasses auch eine 2010 Version des Programmier-Handbuchs gibt, da gibts sie auch, die Sprach-Features im Programmier-Handbuch.
    Das WebSite-Layout der 2010er-Msdn findich wesentlich besser.

    Also die Systematik der MSDN kann einen Suchenden schon zu autoaggressiven Verhalten verleiten. ;)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    So jetzt hab ich mich intensiv mit WPF beschäftigt und es klappt auch schon so einigermassen.
    Nur eine Sache die bekomme ich absolut nicht gebacken. Ich habe eine Textbox "txtQuellpfad" und eine Klasse "clsControls.vb".
    Die Textbox ist mit der Klasse verbunden. Das ganze sieht so aus:

    XML-Quellcode

    1. xmlns:local="clr-namespace:CopyPDF"
    2. <Window.Resources>
    3. <local:clsControls x:Key="txtBoxen" />
    4. </Window.Resources>
    5. <Grid x:Name="gridPfade" VerticalAlignment="Center" DataContext="{Binding Source={StaticResource txtBoxen}}">
    6. <TextBox x:Name="txtQuellpfad"
    7. Text="{Binding TextQuellpfad, Mode=TwoWay}">
    8. </TextBox>


    Die klasse sieht so aus:

    VB.NET-Quellcode

    1. Imports System.Collections.Generic
    2. Imports System.Linq
    3. Imports System.Text
    4. Imports System.ComponentModel
    5. Public Class clsControls
    6. Implements INotifyPropertyChanged
    7. 'Events
    8. Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    9. Private m_Quellpfad As String
    10. ' Create the OnPropertyChanged method to raise the event
    11. Private Sub OnPropertyChanged(ByVal info As String)
    12. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    13. End Sub
    14. Private Sub UpdateSavings(sKey As String, sValue As String)
    15. putRegistry(sKey, sValue)
    16. End Sub
    17. ' Properties
    18. Public Property TextQuellpfad As String
    19. Get
    20. Return m_Quellpfad
    21. End Get
    22. Set(value As String)
    23. If Me.TextQuellpfad <> value Then
    24. m_Quellpfad = value
    25. NotifyPropertyChanged("TextQuellpfad")
    26. Me.UpdateSavings("Quellpfad", value)
    27. End If
    28. End Set
    29. End Property
    30. Private Sub NotifyPropertyChanged(propertyname As String)
    31. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyname))
    32. End Sub
    33. End Class


    Wenn ich das Programm starte hol ich mir aus der Registry den String der in die Textbox soll

    VB.NET-Quellcode

    1. Dim m_Controls = New clsControls()
    2. m_Controls.TextQuellpfad = Convert.ToString(RK.GetValue("Quellpfad", "Bitte Quellpfad eingeben!"))


    Leider wird der Text aus der Registry nicht in die Textbox übernommen und ich hab schon alles mögliche versucht leider ohne Erfolg.
    Vielleicht kann mir einer auf die Sprünge helfen, wäre super.
    es fehlen halt Grundlagen.

    Ist dir klar, was das Schlüsselwort New macht? Offensichtlich nicht.

    Weiters wird dir unklar sein, wie im Xaml eine Instanz erstellt wird (das geht nämlich ohne New).

    Mit dem Ergebnis, dass du in den Xaml-Resourcen eine clsControls-Instanz hast, und im Code eine andere.
    Da muß man sich eigentlich nicht wundern, wenn das Xaml nix davon mitbekommt, wenn du die Änderung in der anneren clsControls-Instanz vornimmst.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()