Ich führe eine Liste der aktuellen Alarme und Ereignisse in einem grundlegenden Datagrid. Der Benutzer kann durch die Liste scrollen. Der Benutzer kann einen Punkt auswählen und diesen bestimmten Alarm bestätigen. Das funktioniert.

Der Benutzer sollte auch laut sein, um alle sichtbaren Elemente zu bestätigen. Hier stecke ich fest. Ist es möglich, eine Liste der aktuellen Sammlungen aus einem Datagrid abzurufen?

Teil von XAML

<Grid Background="DarkGray">
    <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Vertical">
            <Button Content="Ack visible" Command="{Binding AcknowledgeVisibleCommand}"/>
            <Button Content="Ack selected" Command="{Binding AcknowledgeSelectedCommand}"/>
        </StackPanel>    
        <DataGrid ItemsSource="{Binding AlarmAndEventList}"  SelectedItem="{Binding SelectedAlarmItem}" Background="DarkGray" IsReadOnly="True">
        </DataGrid>
    </StackPanel>
</Grid>

Teil von ViewModel

public ObservableCollection<AlarmItem> AlarmAndEventList { get { return  _AlarmAndEventList; } }

    private void AcknowledgeVisible()
    {
        //Do something with a list of visible items in datagrid
    }

    private void AcknowledgeSelected()
    {
        if (SelectedAlarmItem != null)
        {
            AlarmAndEventInstance.updateAlarmItem(SelectedAlarmItem);
        }


    }

Außerdem möchte ich den Befehl "Einzelbestätigung" ausführen, wenn der Benutzer auf ein Element doppelklickt. Was ist die "MVVM-Methode", um auf einen Doppelklick auf ein Datagrid zu reagieren?

1
Snovva1 23 Dez. 2015 im 05:02

2 Antworten

Beste Antwort

Um die aktuell sichtbaren Elemente in einem DataGrid zu beobachten, habe ich die folgende angehängte Eigenschaft geschrieben:

public class DataGridExtensions
{
    public static readonly DependencyProperty ObserveVisiblePersonsProperty = DependencyProperty.RegisterAttached(
        "ObserveVisiblePersons", typeof(bool), typeof(DataGridExtensions),
        new PropertyMetadata(false, OnObserveVisiblePersonsChanged));

    public static readonly DependencyProperty VisiblePersonsProperty = DependencyProperty.RegisterAttached(
        "VisiblePersons", typeof(List<Person>), typeof(DataGridExtensions),
        new PropertyMetadata(null));

    private static readonly DependencyProperty SenderDataGridProperty = DependencyProperty.RegisterAttached(
        "SenderDataGrid", typeof(DataGrid), typeof(DataGridExtensions), new PropertyMetadata(default(DataGrid)));

    private static void OnObserveVisiblePersonsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DataGrid dataGrid = d as DataGrid;
        if (dataGrid == null)
            return;
        dataGrid.Loaded += DataGridLoaded;
    }

    private static void DataGridLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        DataGrid dataGrid = (DataGrid) sender;
        dataGrid.Loaded -= DataGridLoaded;
        ScrollViewer scrollViewer = FindChildren<ScrollViewer>(dataGrid).FirstOrDefault();
        if (scrollViewer != null)
        {
            SetSenderDataGrid(scrollViewer, dataGrid);
            scrollViewer.ScrollChanged += ScrollViewerOnScrollChanged;
        }
    }

    public static void SetObserveVisiblePersons(DependencyObject element, bool value)
    {
        element.SetValue(ObserveVisiblePersonsProperty, value);
    }

    public static bool GetObserveVisiblePersons(DependencyObject element)
    {
        return (bool) element.GetValue(ObserveVisiblePersonsProperty);
    }

    private static void SetSenderDataGrid(DependencyObject element, DataGrid value)
    {
        element.SetValue(SenderDataGridProperty, value);
    }

    private static DataGrid GetSenderDataGrid(DependencyObject element)
    {
        return (DataGrid) element.GetValue(SenderDataGridProperty);
    }

    private static void ScrollViewerOnScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        ScrollViewer scrollViewer = sender as ScrollViewer;
        if (scrollViewer == null)
            return;

        ScrollBar verticalScrollBar =
            FindChildren<ScrollBar>(scrollViewer).FirstOrDefault(s => s.Orientation == Orientation.Vertical);
        if (verticalScrollBar != null)
        {
            DataGrid dataGrid = GetSenderDataGrid(scrollViewer);

            int totalCount = dataGrid.Items.Count;
            int firstVisible = (int) verticalScrollBar.Value;
            int lastVisible = (int) (firstVisible + totalCount - verticalScrollBar.Maximum);

            List<Person> visiblePersons = new List<Person>();
            for (int i = firstVisible; i <= lastVisible; i++)
            {
                visiblePersons.Add((Person) dataGrid.Items[i]);
            }
            SetVisiblePersons(dataGrid, visiblePersons);
        }
    }

    public static void SetVisiblePersons(DependencyObject element, List<Person> value)
    {
        element.SetValue(VisiblePersonsProperty, value);
    }

    public static List<Person> GetVisiblePersons(DependencyObject element)
    {
        return (List<Person>) element.GetValue(VisiblePersonsProperty);
    }

    private static IList<T> FindChildren<T>(DependencyObject element) where T : FrameworkElement
    {
        List<T> retval = new List<T>();
        for (int counter = 0; counter < VisualTreeHelper.GetChildrenCount(element); counter++)
        {
            FrameworkElement toadd = VisualTreeHelper.GetChild(element, counter) as FrameworkElement;
            if (toadd != null)
            {
                T correctlyTyped = toadd as T;
                if (correctlyTyped != null)
                {
                    retval.Add(correctlyTyped);
                }
                else
                {
                    retval.AddRange(FindChildren<T>(toadd));
                }
            }
        }
        return retval;
    }
}

Und in der xaml in der Definition Ihres DataGrid müssen Sie Folgendes schreiben:

nameSpaceOfAttachedProperty:DataGridExtensions.ObserveVisiblePersons="True"
nameSpaceOfAttachedProperty:DataGridExtensions.VisiblePersons="{Binding VisiblePersons, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Und in Ihrem ViewModel haben Sie eine Eigenschaft wie:

private List<Person> visiblePersons;
public List<Person> VisiblePersons
{
    get { return visiblePersons; }
    set
    {
        visiblePersons = value;
        OnPropertyChanged();
    }
}

Und jedes Mal, wenn Sie scrollen, werden die VisiblePersons aktualisiert.

In Ihrem Fall müssen Sie den Typ der Liste innerhalb des beigefügten Eigentums ändern, um Ihren Anforderungen zu entsprechen.

2
Tomtom 23 Dez. 2015 im 16:34
  1. Sie können die MyDataGrid.Items - Sammlung zum Herausfiltern verwenden.

  2. Sie können die Filterung auch in Ihrem MyDataGrid anwenden. Aber keine gefilterten Elemente anzeigen. So filtern Sie DataGrid

-1
AnjumSKhan 23 Dez. 2015 im 04:37