Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Property an bool binden (WPF)
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

Property an bool binden (WPF)

beantworten | zitieren | melden

Hallo,

ich schlage mich mit einer (sicher dämlichen) Frage rum:
Ich habe ein Overlay in WPF und das hat eine Eigenschaft IsOverlayEnabled. Setzt man dieses auf true, überblendet es die ganze momentane Anzeige. Nun soll die Eigenschaft aber einen boolschen Wert gebunden werden, der sich im Code ändert.
Habe da schon einiges versucht, allerdings reagiert das Element nicht auf die Änderung und ich weiß nicht wieso.

IsOverlayEnabled="{Binding Path=IsOverlay}" oder IsOverlayEnabled="{Binding IsOverlay}" bewirken da nichts.
Auf ner anderen Seite hab ich gelesen, dass man evtl. noch dieses IPropertyChanged einbauen müsste, ist das vllt der springende Punkt?

MfG
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3627
Herkunft: Hannover

beantworten | zitieren | melden

Hallo,

ja du musst INotifyPropertyChanged implementieren. Schau dir dazu mal Beispiele zum Thema MVVM an. Dann wirst du auch sicherlich weiterkommen.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Khalid am .
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
private Nachricht | Beiträge des Benutzers
Ace86
myCSharp.de - Member



Dabei seit:
Beiträge: 15

beantworten | zitieren | melden

Man könnte INotifyPropertyChanged einsetzen oder eine dependency property erstellen.

Hier mal ein Beispiel für INotifyPropertyChanged:


public class myClass : INotifyPropertyChanged
    {
        private int var;
        public event PropertyChangedEventHandler PropertyChanged;

        public int Var
        {
            get { return var; }
            set 
            { 
                var = value;
                OnChanged("Var");
            }
        }

        private void OnChanged(string propertyName) {
            if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Die OnChanged-Methode vereinfacht, das Auslösen von PropertyChanged, wenn man viele Properties hat. Unschön finde ich, dass man den Namen, der Eigenschaft als Zeichenkette angeben muss, aber ich kenne keine andere Lösung dafür.
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1626
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Hallo Ace86,
Zitat von Ace86
Unschön finde ich, dass man den Namen, der Eigenschaft als Zeichenkette angeben muss
Es gibt MVVM-Frameworks wie Cinch bei denen es über Lambda-Expressions geht. Damit fällt das Refaktorisieren leichter. Tools wie ReSharper sind jedoch auch in der Lage die Strings in OnChanged zu refaktorisieren.
Zitat von Ace86
Man könnte INotifyPropertyChanged einsetzen oder eine dependency property erstellen
DP können nur in Klassen eigesetzt werden welche von DependencyObject erben, da ansonsten GetValue und SetValue fehlen. Damit haben sie in einer ViewModel Klasse nichts verloren.

Bindings funktionieren nur an DependencyProperties.
Jedoch kann von allen public und/oder static Properties gebunden werden.

Gruß,
Michael
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
Ace86
myCSharp.de - Member



Dabei seit:
Beiträge: 15

beantworten | zitieren | melden

Zitat
DP können nur in Klassen eigesetzt werden welche von DependencyObject erben, da ansonsten GetValue und SetValue fehlen. Damit haben sie in einer ViewModel Klasse nichts verloren.

Im ersten Beitrag steht nicht, dass es im Zusammenhang mit MVVM verwendet wird. Ich wollte die DPs auch nur als weitere Möglichkeit nennen.
Zitat
Es gibt MVVM-Frameworks wie Cinch bei denen es über Lambda-Expressions geht.

gut zu wissen
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1626
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Zitat
Im ersten Beitrag steht nicht, dass es im Zusammenhang mit MVVM verwendet wird
Ich denke in WPF kann davon ausgegangen werden, dass minimales MVVM betrieben wird, da man ansonsten wieder bei derselben Technologie wie WinForms ist.
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

Erst mal Danke für die ersten Vorschläge.
Ich bin ja auch noch ganz am Anfang ;) von daher ist das MVVM noch nicht ganz umgesetzt.
Ich hab allerdings nach wie vor das Problem, dass sich die Property vom XAML Bauteil nicht mitändert. Habe eine INstanz der Klasse erzeugt

public MyClass bla = new MyClass();
und ändere an gegebener Stelle den Wert

bla.Overlay = true;
aber trotzdem passiert nichts.

In der Baumstruktur im Debugger steht bei PropertyChanged stets

null
.

Das Binding versucht mit

IsOverlayEnabled="{Binding LoadingScreenOverlayEnable}"
oder mit weiteren Pfadangaben zur Instanz oder mit Projektname. Beim Debuggen wird der Wert im Designer (mit der Maus über die Bindingzuweisung fahren) auch richtig angezeigt, nur die Wirkung der Zuweisung (IsOverlayEnabled steht im Debugger unweigerlich auf

false
) zeigt sich nicht.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von JonnyJohnson am .
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Zitat von JonnyJohnson
Habe eine INstanz der Klasse erzeugt und ändere an gegebener Stelle den Wert, aber trotzdem passiert nichts.

[Hinweis] Wie poste ich richtig? 5
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

public class MyClass : INotifyPropertyChanged
ist dabei wie oben aufgebaut.
private Nachricht | Beiträge des Benutzers
Khalid
myCSharp.de - Experte

Avatar #avatar-2534.gif


Dabei seit:
Beiträge: 3627
Herkunft: Hannover

beantworten | zitieren | melden

Setze den BindingMode mal auf TwoWay.
"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

TwoWay hilft leider nicht :(
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Hallo,
Zitat von JonnyJohnson

public class MyClass : INotifyPropertyChanged
ist dabei wie oben aufgebaut.

es ist nicht so fein, dies nachträglich hinzuzufügen.

Auch kann man aus diesen Bruchstücken wie "false" überhaupt nichts sinnvolle unternehmen.

Wo wird die Klasse erzeugt? Wie denkst Du zu erreichen, dass Deine erzeugt Instanz überhaupt benutzt wird? Wie erfolgt die Bindung? Was ist "bla.Overlay", was "LoadingScreenOverlayEnable"?
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

Habs hinzugefügt, weil Editieren nicht möglich war.

IsOverlayEnabled ist die Eigenschaften eines Ladebildschirms, steht das auf "true" überdeckt es das ganze Window (oder Control, je nach dem). Diese Einstellung ist anfangs auf "false" gesetzt. Bei einem Buttonklick soll eine Anfrage per Backfgroundworker gestartet werden. Während der Anfrage soll die GUI gesperrt sein (IsOverlayEnabled sol true werden), jedoch entsteht durch das Überblendmodul nicht der Eindruck, dass alles abgeschmiert wäre, falls der Backgroundworker lange auf Daten warten muss.
Daher soll die Eigenschaft IsOverlayEnabled an ein bool im Code gebunden werden, welcher public gesetzt werden kann. Baut man das ganze also ein, setzt man nur an einer Stelle diesen bool auf true und der Rest passiert von alleine.
Das soll durch das Binding passieren, was bei mir aber nicht hinhaut, da die EIgenschaft IsOVerlayEnabled nicht darauf reagiert.

"bla" ist die Instanz der Klasse "MyClass", über die der bool-Wert gesetzt werden soll.
"LoadingScreenOverlayEnable" ist nur ein weiterer bool-Wert zum Testen, da es bis jetzt mit der PropertyChanged-Variante nicht klappt. Hiermit klappts aber genau so wenig.

Ich hoffe das ganze ist nun etwas klarer.
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Zitat von JonnyJohnson
Ich hoffe das ganze ist nun etwas klarer.

Leider nein, da Du noch immer nicht die wirklich relevanten Code-Teile gepostet hast.
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

Welchen Teil möchtest du denn haben?
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5985
Herkunft: Leipzig

beantworten | zitieren | melden

Hi JonnyJohnson,

versuch dich doch mal in die Leute reinzuversetzen, die dir hier helfen wollen. Was nutzt uns denn der Code, wo du irgendeine Variable zuweist? Du mußt doch am besten wissen, was relevant ist und was nicht! Es reicht eben nicht, irgendwelche unzusammenhängende Codeschnipsel zu posten, sondern es sollte uns helfen, dein Problem nachzuvollziehen.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
Console32
myCSharp.de - Member



Dabei seit:
Beiträge: 266

beantworten | zitieren | melden

Zitat von JonnyJohnson
jedoch entsteht durch das Überblendmodul nicht der Eindruck, dass alles abgeschmiert wäre

Hilft dir jetzt bei deinem Problem nicht weiter aber wieso denkst du das es besser ist das Control einfach zu überblenden ?

Also wenn ein programm bei mir für 5 sekunden ein starres overlay anzeigt entsteht genauso der eindruck das alles abgeschmirt ist. Warum teilst du dem User nicht einfach mit wie weit deine Verarbeitung ist und sperrst die Controls einfach per Enabled = false;
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

Gut, versuchen wirs mal so:

Ich habe in der XAML-Datei als erstes Element (nach dem xlms:-Definitionen) folgendes:

<LoadingSection IsOverlayEnabled="{Binding myclass.Overlay, Mode=TwoWay}" Name="MainOverlay"> (LaodingSection ist dabei ein CustomControl, was bei IsOverlayEnabled = true das Parent überdeckt, bei Bedarf Buttons und eine Fortschrittsanzeige darstellt).
Die Eigenschaft IsOverlayEnabled kann hierbei true oder false sein. Der zugehörige bool-Wert soll ein public-Property sein, der Rest private.

Im Codebehind habe ich die Klasse


public class MyClass : INotifyPropertyChanged
        {
            private bool _overlay;
            public event PropertyChangedEventHandler PropertyChanged;

            public bool Overlay
            {
                get { return _overlay; }
                set
                { 
                _overlay = value;
                OnChanged("Overlay");
                }
            }
            public void OnChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

Welche ich per

private MyClass _myOverlay = new MyClass(); 
zu Beginn instanziiere. Klickt der Benutzer nun auf einen Button, soll die Eigenschaft IsOverlayEnabled auf true gesetzt werden für ein paar Sekunden und nach Ablauf eines Timers wieder auf false. Daher das Binding.

Nun sollte ja (den Erwartungen nach) ein Event auftreten, wenn ich _myOverlay.Overlay ändere, richtig? Durch das Binding sollte dann auch eigentlich IsOverlayEnabled davon Wind bekommen und entsprechend reagieren, tuts aber nicht.

Man könnte sicherlich alles deaktivieren, aber es ist gedacht da auch noch weitere Dinge hinzuzufügen, wobei sich eben die LoadingSection am besten dabei macht. :/ Da ohne weitere Einstellung bei der LoadingSection sich auch noch was bewegt, entsteht der Eindruckt der abgeschmierten Anwendung eben auch nicht. :)
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5985
Herkunft: Leipzig

beantworten | zitieren | melden

Hi JonnyJohnson,

wenn du eine Variable namens _myOverlay setzt, dann solltest du auch nicht gegen eine Eigenschaft namens myclass binden. Falls das überhaupt eine Eigenschaft ist, denn binden geht natürlich nur mit Eigenschaften. Wenn es sich um einen DataBinding-Fehler handelt, wird der auch im Ausgabefenster angezeigt, evtl. solltest du dort mal schauen was passiert.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

Oh, das hatte ich falshc zusammenkopiert.
Ich binde mit IsOverlayEnabled="{Binding _myOverlay.Overlay, Mode=TwoWay}" und auch in der Ausgabe kommt kein Fehler...
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5985
Herkunft: Leipzig

beantworten | zitieren | melden

Hi JonnyJohnson,

so wie ich das sehe, ist _myOverlay ein privates Feld. Mach eine öffentliche Eigenschaft daraus, dann sollte es funktionieren. Es müßte meines Erachtens auch eine Fehlermeldung im Ausgabefenster stehen, die etwas ähnliches besagt. Am besten beliest du dich mal gezielt nach den Möglichkeiten und den Einschränkungen des DataBindings.

Christian
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
teebeast
myCSharp.de - Member



Dabei seit:
Beiträge: 41
Herkunft: Bayern

beantworten | zitieren | melden

Hast Du die Klasse auch an den DataContext gebunden? Sonst weiß er natürlich nicht, worauf er zugreifen soll.

this.DataContext = this._myOverlay;
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von teebeast am .
private Nachricht | Beiträge des Benutzers
JonnyJohnson
myCSharp.de - Member



Dabei seit:
Beiträge: 18

Themenstarter:

beantworten | zitieren | melden

So, nun gehts. :)
Mit


IsOverlayEnabled="{Binding Path=Overlay, Mode=TwoWay}" Name="MainOverlay"
und nach der Instanziierung durch


MainOverlay.DataContext = _myOverlay;

liest er alles richtig aus und das Overlay reagiert, wie es soll :)

Danke.
private Nachricht | Beiträge des Benutzers