Binding zwischen 2 Fenster und einem Control

  • WPF

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Facebamm.

    Binding zwischen 2 Fenster und einem Control

    Hallo zusammen :D,

    ich möchte gern zwei Control von selbem Typ von einem zweiten Fenster aus Steuern.

    Spoiler anzeigen

    HTML-Quellcode

    1. --------------------------------- --------------------------------
    2. |Window1 _ □ x | |Window2 _ □ x |
    3. --------------------------------- --------------------------------
    4. | |------------| |------------| | | ImageLeft: | ImageRight |
    5. | | | | | | | Filter: | Filter: |
    6. | | Image1 | | Image2 | | . -> | |TextBox | | |TextBox | | <- .
    7. | | | | | | | | Filter2: | Filter2: | |
    8. | |------------| |------------| | . -> | |TextBox | | |TextBox | | <- .
    9. --------------------------------- | ................................ |
    10. ^ ^-------------- | ---------------------------------------.
    11. | |
    12. . ------------------------------.


    Was ich bis jetzt herausgefunden habe ist, das ich den DataContext vom Window1 an Window2 geben muss.
    Mein Hauptproblem ist das die Werte nicht ausgetauscht werden zwischen den Fenster und dem Controls.
    Aber wie komme ich and die Property meines jeweiligen Controls?
    Gib es sogar einen besseren Ansatz?

    Mein Aufbau sieht momentan wie folgt aus:

    CamController
    Spoiler anzeigen

    C#-Quellcode

    1. [Designer("CamController")]
    2. public class CamController: Image, INotifyPropertyChanged
    3. {
    4. public event PropertyChangedEventHandler PropertyChanged;
    5. ...
    6. internal int _Threshold1;
    7. public int Threshold1{
    8. get => _Threshold1; set {
    9. if (_Threshold1!= value)
    10. UpdateWithNotify(ref _Threshold1, value);
    11. }
    12. }
    13. ...
    14. private void UpdateWithNotify<T>(ref T source, T value, [CallerMemberName] string propertyName = "")
    15. {
    16. if (!EqualityComparer<T>.Default.Equals(source, value))
    17. {
    18. source = value;
    19. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    20. //Hier bin ich mir mega unsicher ob es nicht zu komplikationen mit dem 'propertyName' kommt
    21. }
    22. }
    23. }

    Window1 - MainWindow.xaml
    Spoiler anzeigen

    XML-Quellcode

    1. <Window
    2. ...
    3. xmlns:local="clr-namespace:OptTwlCtrl"
    4. xmlns:sys="clr-namespace:System;
    5. assembly=mscorlib"mc:Ignorable="d">
    6. ...
    7. <local:CamController ... x:Name="CamLeft" Threshold1="500"/>
    8. <local:CamController ... x:Name="CamRight" Threshold1="500"/>
    9. ...
    10. </Window>


    Window2 - Setting.xaml
    Spoiler anzeigen

    XML-Quellcode

    1. <Window
    2. ...
    3. xmlns:local="clr-namespace:OptTwlCtrl"
    4. xmlns:sys="clr-namespace:System;assembly=mscorlib"
    5. mc:Ignorable="d">
    6. <Window.DataContext>
    7. <local:MainWindow/>
    8. </Window.DataContext>
    9. ...
    10. <TextBox ... Text="{Binding ElementName=CamLeft, Path=Threshold1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    11. <TextBox ... Text="{Binding ElementName=CamRight, Path=Threshold1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    12. ...
    13. </Window>


    MfG

    Facebamm :D

    Edit: Window1 Copy/Past fix

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

    Hallo

    Hast du Bindingfehler im Ausgabefenster?

    Wenn nicht stimt das Binding schon mal.
    Wo legst du denn das Binding vom Fenster 2 fest? Den Code sehe ich nicht.

    Du solltest auf jeden Fall das Property des "CamController" als DependencyProperties implementieren.
    Tutorialreihe <WPF lernen/>

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Gut part 1 hab ich mit dem DependencyProperties

    CamController.cs
    Spoiler anzeigen

    C#-Quellcode

    1. public class CamController: Image, INotifyPropertyChanged
    2. {
    3. public int Threshold1 {
    4. get => GetDependencyProperty<int>(Threshold1Property);
    5. set => SetDependencyProperty(Threshold1Property, value);
    6. }
    7. public static readonly DependencyProperty Threshold1Property = DependencyProperty.Register("Threshold1", typeof(int), typeof(CamController), new PropertyMetadata(null));
    8. //...
    9. public void SetDependencyProperty<T>(DependencyProperty property, T value)
    10. {
    11. if (Dispatcher.CheckAccess())
    12. {
    13. Dispatcher.Invoke(()
    14. => SetValue(property, value),
    15. DispatcherPriority.Background);
    16. }
    17. else
    18. {
    19. SetValue(property, value);
    20. }
    21. }
    22. public T GetDependencyProperty<T>(DependencyProperty property)
    23. => Dispatcher.CheckAccess()
    24. ? (T)GetValue(property) //Access true
    25. : (T)Dispatcher.Invoke( //Access false
    26. (DispatcherOperationCallback)delegate
    27. {
    28. return GetValue(property);
    29. },
    30. DispatcherPriority.Background,
    31. property);
    32. }




    was meinst du genau mit -Wo legst du denn das Binding vom Fenster 2 fest? Den Code sehe ich nicht.-?
    Vorab der antwort evtl:
    ​Text="{Binding Threshold1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:FalconController}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" so sieht es jetzt aus aber meine Werte werden immer noch nicht ausgetauscht.
    Vorher: ​Text="{Binding ElementName=CamLeft, Path=Threshold1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

    ps ich hoffe das war richtig geantwortet

    MfG

    Facebamm

    Facebamm schrieb:

    was meinst du genau mit -Wo legst du denn das Binding vom Fenster 2 fest?

    Du musst ja irgendwo den DataContext für das Fenster 2 auf den DataContext des Fenster 1 setzen.

    z.b. so: mywin2Instanz.DataContext = Me.DataContext

    Das geht NUR über Code, den code würde ich gerne sehen.

    Weil das hier:

    XML-Quellcode

    1. <Window.DataContext>
    2. <local:MainWindow/>
    3. </Window.DataContext>


    Klapt nicht. Dadurch wird eine NEUE Instanz von MainWindow erstellt. Du musst aber die Vorhandene Instanz übergeben.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    -Weil das hier: .... NEUE Instanz von MainWindow erstellt-, ahhh das wusste ich nicht :D

    dann wäre es doch:

    C#-Quellcode

    1. Setting setting = new Setting()
    2. {
    3. DataContext = this.DataContext //
    4. };
    5. setting.Show();


    Edit:

    Dann habe ich immer noch das Problem, das ich zweimal das selbe Control habe in meinem Window1 und via RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:FalconController}} doch nicht auf mein jeweiliges Control komme
    Hallo

    Verstehe dein Problem, du solltest ja auch nicht auf das Control direkt binden, sondern auf Daten.

    Du machst dir eine Klasse, oder gegebenenfalls in der CodeBehind des Window1 Properties wie zb. Threshold.
    Beide Fenster sind an diese Klasse begunden, und deren Controls auch. Wenn dann beide Fenster die selbe Instanz der Klasse als Datencontext haben wir auch alles Syncronisiert.

    Soll ich dir ein Demo machen??

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Also,
    Binding zwischen den beiden Fenstern geht ohne IDE Fehler.

    Aber sobald ich die Application starte ... naja ... kommen ein Fehler.
    NullReferenceException, das kann aber auch an der Art und weise liegen wie ich es gemacht habe.

    Ich versuch mal mein Bad-Praktis and Dont Copy shit zu erklären:

    XML-Quellcode

    1. Also ich habe in der App.xaml -> Application.Ressourcess -> CamSetting - .
    2. |
    3. . ---------------------------------------------------------------------- .
    4. |
    5. . -> MainWindow -> . -> CamLeftSetting -> Threshold1 -> CamLeft
    6. | |
    7. | . -> CamRightSetting -> Threshold1 -> CamRight
    8. | *^^*
    9. | *||*
    10. | *||* Automatische änderung
    11. | *||*
    12. . -> Setting -> . -> CamLeftSetting -> Threshold1 -> TextboxForLeftCam - .
    13. | ^ |
    14. | . <------- NewThreshold1 <------------------ .
    15. |
    16. . -> CamRightSetting -> Threshold1 -> TextboxForRightCam - .
    17. ^ |
    18. . <-------- NewThreshold1 <------------------- .

    Spoiler anzeigen


    C#-Quellcode

    1. public class CamSetting : DependencyObject, INotifyPropertyChanged
    2. {
    3. public event PropertyChangedEventHandler PropertyChanged;
    4. private int _threshold1; //Warum ich hier auslager, damit ich schnell von Threads aus zugreife
    5. [Category("Cam")] public int Threshold1 {
    6. get => _threshold1;
    7. set => UpdateWithNotify(
    8. ref _threshold1,
    9. value,
    10. Threshold1Property);
    11. }
    12. public static DependencyProperty Threshold1Property;
    13. public CamSetting () : base()
    14. {
    15. _threshold1 = 200;
    16. }
    17. protected void UpdateWithNotify<T>(ref T source, T value, DependencyProperty property, [CallerMemberName] string propertyName = "")
    18. {
    19. if (!EqualityComparer<T>.Default.Equals(source, value))
    20. {
    21. source = value;
    22. Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => SetValue(property, value)));
    23. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    24. }
    25. }
    26. }


    XML-Quellcode

    1. <Application.Resources>
    2. ...
    3. <Falcon:CamSetting x:Key="CamLeftSettings" Threshold1="500" />
    4. <Falcon:CamSetting x:Key="CamRightSettings" Threshold1="500" />
    5. ...
    6. </Application.Resources>


    C#-Quellcode

    1. public class CamView: Image, INotifyPropertyChanged
    2. {
    3. ...
    4. public event PropertyChangedEventHandler PropertyChanged;
    5. public CamSetting CamSetting { get; set; }
    6. public static DependencyProperty CamSettingProperty = DependencyProperty.Register(nameof(CamSetting), typeof(CamSetting ), typeof(CamView));
    7. ...
    8. }


    Btw.: CamSetting ist trz. binding immer null


    XML-Quellcode

    1. <Window
    2. ...
    3. <FalconUI:FalconView x:Name="CamLeft" Stretch="Fill" FalconSetting="{Binding Source={StaticResource CamLeftSettings}, Mode=OneWay}" />
    4. <FalconUI:FalconView x:Name="CamRight" Grid.Column="1" Stretch="Fill" FalconSetting="{Binding Source={StaticResource CamRightSettings}, Mode=OneWay}"/>
    5. ...
    6. </Window>


    XML-Quellcode

    1. <Window
    2. ...
    3. <TextBox x:Name="TxbCamLeftThresholdOne" Text="{Binding Source={StaticResource CamLeftSettings}, Path=Threshold1, Mode=TwoWay}"/>
    4. <TextBox x:Name="TxbCamRightThresholdOne" Text="{Binding Source={StaticResource CamRightSettings}, Path=Threshold1, Mode=TwoWay}"/>
    5. ...
    6. </Window>





    MfG

    Facebamm
    Hallo

    Nein, Binding auf eine StatisResource klappt nicht.

    Zwei möglichkeiten, entweder du ladest das Projekt hoch und ich sehe mir das mal an, weil ich verstehe leider anhand der "Grafik" nix oder ich mach dir eine Demo anhand eines normalen Control wie z.b. der Textbox in zwei Fenstern.

    Was ist dir lieber??

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Ich nehm variante 2, möchte selbst noch das Binding besser verstehen D:

    Darf ich Bedingungen hinzufügen, die es dann leichter machen mein Problem zu lösen?

    Also: Ein eingenes Control mit einer neuen Property.
    Welches, dann doppelt im ersten Fenster liegt.
    Im zweiten Fenster müssten nun die beiden Controls dessen neue Property verändert werden

    :D

    Ich danke dir schonmal in vorraus @Nofear23m

    MfG

    Facebamm

    Facebamm schrieb:

    Darf ich Bedingungen hinzufügen

    Wenns weiter nix ist. ;)

    OK, mach ich sobald ich daheim bin.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo

    Anbei ein Projekt.

    Was habe ich gemacht:
    Ein CustomControl mit einem Image und einem NotificationIcon. Was besseres für ein Eigenständiges Control ist mir auf die schnelle nicht eingefallen.



    Es öffnen sich zwei Fenster. Beide haben die selbe Instanz der Klasse TestClass als DatenContext. vom zweiten Fenster aus lässt sich nun über Binding der NotificationCount ändern.

    Grüße
    Sascha
    Dateien
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Okay, ich hab mir das ganze Projekt jetzt von dir angeschaut und muss ehrlich sein, das ich noch einwenig über wpf lesen werde via wie das alles zusammenhäng und so weiter mit dem Binding :D

    Ich melde mich sobald ich einen neuen Fortschritt habe :D

    Danke dir :D

    MfG

    Facebamm