none
WPF - Routed Events in MVVM RRS feed

  • Frage

  • Hallo,

    arbeite mich gerade in WPF-MVVM ein.

    Databinding und Commands als Trennung von Design und Logik hab ich verstanden und setze es so ein.

    Was mach ich aber, wenn ich routed events behandeln will?

    Z.B. SelectedIndexChanging/Changed-Event (in Treeviews, Datagrids, Listviews, etc.).

    Manchmal benötigt man die Event-Args um einen Vorgang zu canceln, abzuhandeln, z.B.

    e.Handled = true; e.Cancel = true;

    Es gibt wohl auch Frameworks dafür (z.B. MVVM Light), die einen Event in einen Command "konvertieren".

    Ist das der richtige Weg die Trennung von Design und Logik einzuhalten?

    Wie machen das die Experten?

    Danke und Gruß.

    Montag, 30. Oktober 2017 11:01

Antworten

  • Hi,
    wenn Du von einem Steuerelement der Oberfläche ein Ereignis fangen willst, dann nutze die Interactivity dll. Du erzeugst ein Klasse, die von Behavior erbt und dort hast Du die Ereignisse des Steuerelementes:

      public class Window15Behavior : Behavior<TextBox>
      {
        protected override void OnAttached() =>
          AssociatedObject.TextChanged += AssociatedObject_TextChanged; 
        protected override void OnDetaching() =>
          AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
        private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
        {
          var tb = sender as TextBox;
          tb.CaretIndex = tb.Text.Length;
          tb.ScrollToEnd();
        }
      }

    XAML:

            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
     
    ...
    
        <TextBox Text="{Binding Anzeige}">
          <i:Interaction.Behaviors>
            <local:Window15Behavior/>
          </i:Interaction.Behaviors>
        </TextBox>


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks


    Montag, 30. Oktober 2017 11:24

Alle Antworten

  • Hi,
    wenn Du von einem Steuerelement der Oberfläche ein Ereignis fangen willst, dann nutze die Interactivity dll. Du erzeugst ein Klasse, die von Behavior erbt und dort hast Du die Ereignisse des Steuerelementes:

      public class Window15Behavior : Behavior<TextBox>
      {
        protected override void OnAttached() =>
          AssociatedObject.TextChanged += AssociatedObject_TextChanged; 
        protected override void OnDetaching() =>
          AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
        private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
        {
          var tb = sender as TextBox;
          tb.CaretIndex = tb.Text.Length;
          tb.ScrollToEnd();
        }
      }

    XAML:

            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
     
    ...
    
        <TextBox Text="{Binding Anzeige}">
          <i:Interaction.Behaviors>
            <local:Window15Behavior/>
          </i:Interaction.Behaviors>
        </TextBox>


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks


    Montag, 30. Oktober 2017 11:24
  • Hallo Peter,

    danke für die Antwort.

    Scheint grundsätzlich zu funktionieren. Allerdings motzt der Compiler im XAML, dass ich ein zu

    altes Expression-Blend SDK verwende.

    "The type 'TreeViewEvents' from assembly ... is build with an older version of the Blend SDK, and is not supported in a Windows Presentation Framework 4 project."

    Dabei stammt die System.Windows.Interactiviy-Dll aus dem 4.5 Framework und mein Projekt ist auch

    als 4.5 Framework-Projekt gebildet.

    Ok, danke erstmal.

    Gruß.

    Montag, 30. Oktober 2017 12:57