none
Datagrid - markierte Zeilen durchlaufen - wpf - EF RRS feed

  • Frage

  • Hallo,

    ich habe ein Datagrid in dem es möglich ist mehrere Zeilen zu markieren.

    Wie kann ich jetzt für jede Zeile einen Wert aus einer Spalte auslesen?

    Bei einer Zeile löse ich es bisher ((qry_Result)dgDaten.SelectedItem).cntNr;

    Wie kann ich es bei mehreren Zeilen umsetzen?

    DANKE
    Ralf

    Donnerstag, 2. März 2017 11:37

Antworten

  • Hallo Ralf,

    die Grundlagen der Programmiersprache muss man schon beherrschen, sonst wird das mit der UI Entwicklung sehr schwer.

    foreach(qry_Result selectedItem in dgDaten.SelectedItems){
      //hier kannst du nun selectedItem auslesen. 
      //Der Code in der Schleife wird für jedes ausgewählte Item einmal aufgerufen, mit geändertem selectedItem
    }

    Für die bessere Lösung mit dem DataBinding musst du Bindings verstehen. Dann findest du unzählige Beispiele wie eine Binding zu SelectedItems funktioniert (Beispiel).


    Viele Grüße, Tom Lambert - MVP, MCC und MSP
    Wozu Antworten markieren und Posts bewerten? Klicke hier
    Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
    Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub

    Samstag, 4. März 2017 18:14
    Moderator
  • Hi Ralf,
    Tom hat Dir ja schon eine Variante mit CodeBehind gezeigt.

    Etwas professioneller mit MVVM könnte es so aussehen. Für einen Anfänger wird es vielleicht etwas zu komplex sein, aber, wenn Du die Lösung verstehst, dann hast Du einen großen Schritt gemacht. Ansonsten ist die Lösung vielleicht als Anregung für andere Mitleser. Um an die SelectedItems-Eigenschaft ranzukommen, habe ich ein Behavior genutzt.

    XAML:

    <Window x:Class="WpfApplication1.Window58"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
            Title="Window58" Height="300" Width="300">
      <Window.Resources>
        <local:Window58VM x:Key="vm"/>
        <Style TargetType="DataGrid" >
          <Setter Property="local:Window58DataGridBehavior.UseBehavior" Value="True"/>
        </Style>
      </Window.Resources>
        <Grid DataContext="{StaticResource vm}">
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <DataGrid Name="dg" ItemsSource="{Binding View}" />
        <Button Grid.Row="1" Content="Anzeige" Command="{Binding Cmd}"/>
      </Grid>
    </Window>

    ViewModel dazu:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Interactivity;
    
    namespace WpfApplication1
    {
      public class Window58VM : INotifyPropertyChanged
      {
        #region  Properties
    
        private CollectionViewSource cvs;
    
        public ICollectionView View
        {
          get
          {
            if (cvs == null) cvs = new CollectionViewSource() { Source = col };
            return cvs.View;
          }
        }
    
        public IList SelectedCol { get; set; }
    
    
        public ICommand Cmd { get { return new RelayCommand(CmdExec); } }
    
        private void CmdExec(object obj)
        {
          string msg = string.Empty;
          foreach (Window58Data item in SelectedCol) { msg += $"{item.ID}: {item.Info}{Environment.NewLine}"; }
          MessageBox.Show(msg);
        }
    
        private IEnumerable<Window58Data> col
        {
          get
          {
            ObservableCollection<Window58Data> liste = new ObservableCollection<Window58Data>();
            for (int i = 1; i < 100; i++) { yield return new Window58Data() { ID = i, Info = $"Name {i}" }; }
          }
        }
        #endregion
    
    
        #region  OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
      }
    
      public class Window58Data
      {
        public int ID { get; set; }
        public String Info { get; set; }
      }
    
      public class Window58DataGridBehavior : Behavior<DataGrid>
      {
        public static DependencyProperty UseBehaviorProperty =
          DependencyProperty.RegisterAttached("UseBehavior", typeof(Boolean),
                                              typeof(Window58DataGridBehavior),
                                              new UIPropertyMetadata(false, OnUseBehaviorChanged));
    
        public static bool GetUseBehavior(DependencyObject obj) { return (bool)(obj.GetValue(UseBehaviorProperty)); }
        public static void SetUseBehavior(DependencyObject obj, bool value) { obj.SetValue(UseBehaviorProperty, value); }
    
        private static void OnUseBehaviorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          if (e.NewValue.Equals(true)) Interaction.GetBehaviors(d).Add(new Window58DataGridBehavior());
        }
        protected override void OnAttached()
        {
          base.OnAttached();
          var dg = this.AssociatedObject;
          ((Window58VM)dg.DataContext).SelectedCol = dg.SelectedItems;
        }
        protected override void OnDetaching() { base.OnDetaching(); }
      }
    }


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


    Samstag, 4. März 2017 18:50

Alle Antworten

  • Hi Ralfe,
    durchlaufe zyklisch einfach die SelectedItems-Auflistung.

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

    Donnerstag, 2. März 2017 11:48
  • Hallo,

    der Weg von Peter Fleischer ist gut, ich würde die SelectedItems nicht pollen sondern mit einer ObservableCollection binden und auf das CollectionChanged Event reagieren. Am besten im ViewModel (MVVM)

    Hoffe das hilft.

    Viele Grüße

    Wolfgang

    Freitag, 3. März 2017 08:44
  • Hallo,

    entschuldigt die Dumme Frage bin aber ein NewBie, gibt es dazu ein Beispiel ich hab leider keins gefunden.

    DANKE

    Samstag, 4. März 2017 15:20
  • Hallo Ralf,

    die Grundlagen der Programmiersprache muss man schon beherrschen, sonst wird das mit der UI Entwicklung sehr schwer.

    foreach(qry_Result selectedItem in dgDaten.SelectedItems){
      //hier kannst du nun selectedItem auslesen. 
      //Der Code in der Schleife wird für jedes ausgewählte Item einmal aufgerufen, mit geändertem selectedItem
    }

    Für die bessere Lösung mit dem DataBinding musst du Bindings verstehen. Dann findest du unzählige Beispiele wie eine Binding zu SelectedItems funktioniert (Beispiel).


    Viele Grüße, Tom Lambert - MVP, MCC und MSP
    Wozu Antworten markieren und Posts bewerten? Klicke hier
    Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
    Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub

    Samstag, 4. März 2017 18:14
    Moderator
  • Hi Ralf,
    Tom hat Dir ja schon eine Variante mit CodeBehind gezeigt.

    Etwas professioneller mit MVVM könnte es so aussehen. Für einen Anfänger wird es vielleicht etwas zu komplex sein, aber, wenn Du die Lösung verstehst, dann hast Du einen großen Schritt gemacht. Ansonsten ist die Lösung vielleicht als Anregung für andere Mitleser. Um an die SelectedItems-Eigenschaft ranzukommen, habe ich ein Behavior genutzt.

    XAML:

    <Window x:Class="WpfApplication1.Window58"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication1"
            mc:Ignorable="d"
            Title="Window58" Height="300" Width="300">
      <Window.Resources>
        <local:Window58VM x:Key="vm"/>
        <Style TargetType="DataGrid" >
          <Setter Property="local:Window58DataGridBehavior.UseBehavior" Value="True"/>
        </Style>
      </Window.Resources>
        <Grid DataContext="{StaticResource vm}">
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <DataGrid Name="dg" ItemsSource="{Binding View}" />
        <Button Grid.Row="1" Content="Anzeige" Command="{Binding Cmd}"/>
      </Grid>
    </Window>

    ViewModel dazu:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Interactivity;
    
    namespace WpfApplication1
    {
      public class Window58VM : INotifyPropertyChanged
      {
        #region  Properties
    
        private CollectionViewSource cvs;
    
        public ICollectionView View
        {
          get
          {
            if (cvs == null) cvs = new CollectionViewSource() { Source = col };
            return cvs.View;
          }
        }
    
        public IList SelectedCol { get; set; }
    
    
        public ICommand Cmd { get { return new RelayCommand(CmdExec); } }
    
        private void CmdExec(object obj)
        {
          string msg = string.Empty;
          foreach (Window58Data item in SelectedCol) { msg += $"{item.ID}: {item.Info}{Environment.NewLine}"; }
          MessageBox.Show(msg);
        }
    
        private IEnumerable<Window58Data> col
        {
          get
          {
            ObservableCollection<Window58Data> liste = new ObservableCollection<Window58Data>();
            for (int i = 1; i < 100; i++) { yield return new Window58Data() { ID = i, Info = $"Name {i}" }; }
          }
        }
        #endregion
    
    
        #region  OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
      }
    
      public class Window58Data
      {
        public int ID { get; set; }
        public String Info { get; set; }
      }
    
      public class Window58DataGridBehavior : Behavior<DataGrid>
      {
        public static DependencyProperty UseBehaviorProperty =
          DependencyProperty.RegisterAttached("UseBehavior", typeof(Boolean),
                                              typeof(Window58DataGridBehavior),
                                              new UIPropertyMetadata(false, OnUseBehaviorChanged));
    
        public static bool GetUseBehavior(DependencyObject obj) { return (bool)(obj.GetValue(UseBehaviorProperty)); }
        public static void SetUseBehavior(DependencyObject obj, bool value) { obj.SetValue(UseBehaviorProperty, value); }
    
        private static void OnUseBehaviorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          if (e.NewValue.Equals(true)) Interaction.GetBehaviors(d).Add(new Window58DataGridBehavior());
        }
        protected override void OnAttached()
        {
          base.OnAttached();
          var dg = this.AssociatedObject;
          ((Window58VM)dg.DataContext).SelectedCol = dg.SelectedItems;
        }
        protected override void OnDetaching() { base.OnDetaching(); }
      }
    }


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


    Samstag, 4. März 2017 18:50
  • Hallo Peter,

    Ralf stellt hier die Fragen, danke für die ausführliche Erklärung.

    MVVM, Databinding usw. ist kein unbekanntes Gebiet für mich. 

    Hallo Ralf,

    wenn du mehr über das Thema WPF, Binding usw. wissen möchtest.

    Schau mal auf die Seite vom Christion Mosers, hier findest du viele Informationen zum Thema WPF (hat mir am Anfang auch sehr geholfen)

    https://www.wpftutorial.net/DataBindingOverview.html

    Viele Grüße

    Wolfgang

    Samstag, 4. März 2017 19:54
  • Hi Wolfgang,
    vielen Dank für die Info. Ich habe meinen Beitrag korrigiert und an Ralf adressiert.

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

    Sonntag, 5. März 2017 09:37