Laden...

DataGrid | Lösungsansatz Modell Arbeitswoche

Erstellt von jbrown vor einem Jahr Letzter Beitrag vor einem Jahr 815 Views
J
jbrown Themenstarter:in
18 Beiträge seit 2021
vor einem Jahr
DataGrid | Lösungsansatz Modell Arbeitswoche

Guten Abend,

ich suche nach einem Lösungsansatz. Ich möchte eine Arbeitswoche über 7 Spalten darstellen, welche initial je 10 Zeilen für ein Employee - Drop bereitstellt (siehe Bild im Anhang). Aktuell habe ich mich hier für ein DataGrid als Basis entschieden und versuche dies entsprechend meiner Ideen zu modifizieren. Hierbei suche ich nach für mich attraktiven Varianten ein Modell zu entwickeln, welches "einfach" gebunden und via ViewModel modifiziert werden kann. Mein aktueller Ansatz sieht aktuell so aus, erscheint mir aber unnötig kompliziert. Habt ihr andere Ansätze?


public class MatrixSource : ObservableCollection<MatrixRow>
    {
        public MatrixSource(int year, int week, string workingArea, ShiftEnum shift, int initialRowCount = 10)
        {            
            WeekOfYear = year;
            Week = week;
            WorkingArea = workingArea;
            Shift = shift;
            DateRange = DateProvider.Get_WeekDateRangeOf(week, year);

            Build(DateRange, initialRowCount);
        }
        public List<MatrixColumn> ColumnInfoList
        { get; private set; }

        private void
            Build(CalendarDateRange dateRange, int initialRowCount)
        {
            #region create columninfos

            ColumnInfoList = new List<MatrixColumn>();
            
            var startDate = dateRange.Start.Date;

            while(startDate < dateRange.End.Date.AddDays(1))
            {
                var columnHeader = new ShiftHeaderData(new DateInfo(startDate), ShiftEnum.Unbekannt, string.Empty, string.Empty);
                var columnInfo 
                    = new MatrixColumn(this, ColumnInfoList.Count, columnHeader);

                ColumnInfoList.Add(columnInfo);

                startDate = startDate.AddDays(1);
            }

            #endregion

            #region create default rows

            for (int rowIndex = 0; rowIndex < 10; rowIndex++)
            {
                var row = new MatrixRow(this, rowIndex, ColumnInfoList.Count);
                row.OnRowDataChanged += Row_DataChanged;

                Add(row);
            }                

            #endregion
        }


public class MatrixColumn : BaseNotify
    {
        public MatrixColumn(MatrixSource parent, int displayIndex, ShiftHeaderData headerData)
        {
            ParentMatrix= parent;
            DisplayIndex = displayIndex;
            HeaderData = headerData;
        }

        #region properties

        public MatrixSource ParentMatrix
        { get; private set; }

        public ShiftColumn ParentColumn
        { get; set; }

        public int DisplayIndex 
        { get; private set; }

        public ShiftHeaderData HeaderData 
        { get; private set; }

        #endregion
    }


public class MatrixRow : ObservableCollection<EmployeeCellData> , INotifyPropertyChanged
    {
        public MatrixRow(MatrixSource parentMatrix, int displayIndex, int defaultCellCount = 7)
        {
            ParentMatrix = parentMatrix;
            DisplayIndex = displayIndex;

            for (int cellIndex = 0; cellIndex < defaultCellCount; cellIndex++)
            {
                var cell = new EmployeeCellData(parentMatrix, this);

                cell.OnDataChanged += Cell_OnDataChanged;

                Add(cell);
            }
        }
   }

In XAML binde ich so:


<local:ShiftDataGrid x:Name="DebugDG" Grid.Column="1" Grid.Row="1" MinRowHeight="30"                                 
                                 GenerateDefaultMatrixSource="True"
                                 MatrixSource="{Binding Path=MatrixSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

Damit mein DataGrid damit auch was anfangen kann:


public class ShiftDataGrid : DataGrid, INotifyPropertyChanged
    {
        public ShiftDataGrid()
        {
            InitMe();
        }

        #region events

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        #endregion

        #region properties
       
        public static readonly DependencyProperty MatrixSourceProperty = DependencyProperty.Register("MatrixSource", typeof(MatrixSource), typeof(ShiftDataGrid), new PropertyMetadata(OnMatrixSourceChanged));
        public MatrixSource MatrixSource
        {
            get { return (MatrixSource)GetValue(MatrixSourceProperty); }
            set
            {
                SetValue(MatrixSourceProperty, value);
            }
        }

        public static readonly DependencyProperty GenerateDefaultMatrixSourceProperty = DependencyProperty.Register("GenerateDefaultMatrixSource", typeof(bool), typeof(ShiftDataGrid), new PropertyMetadata(false));
        public bool GenerateDefaultMatrixSource
        {
            get { return (bool)GetValue(GenerateDefaultMatrixSourceProperty); }
            set
            {
                SetValue(GenerateDefaultMatrixSourceProperty, value);
            }
        }
        private void
            Build_Matrix(MatrixSource matrixData)
        {
            IsBusy = true;
            {
                SelectedCells?.Clear();
                SelectedLastEmployeeCell = null;
                Columns?.Clear();

                if (matrixData != null)
                {
                    foreach (var columnInfo in matrixData.ColumnInfoList)
                    {
                        columnInfo.ParentColumn 
                            = new ShiftColumn(columnInfo.HeaderData);

                        Columns.Add(columnInfo.ParentColumn);
                    }

                    ItemsSource = matrixData;
                }
            }
            IsBusy = false;
        }

        private static void
            OnMatrixSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ShiftDataGrid).Build_Matrix(e.NewValue as MatrixSource);
        }


Und eine entsprechende DataGridColumn:


public class ShiftColumn : DataGridBoundColumn
    {
        public ShiftColumn(ShiftHeaderData headerData)
        {
            this.Header = headerData;
        }
       protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        {
            EmployeeCellPresenter presenter = new EmployeeCellPresenter() //<----- UserControl als Drag&Drop target/sourc
            {                
                IsDragEnabled = true,
                IsDragIndicatorEnabled = true,
                IsDropEnabled = true,
                IsDropIndicatorEnabled = true
            };

            Binding binding;

            #region bind DataContext

            binding = new Binding();
            {
                binding.Source = cell;
                binding.Mode = BindingMode.TwoWay;
                binding.Path = new PropertyPath("DataContext");
            }
            BindingOperations.SetBinding(presenter, EmployeeCellPresenter.DataContextProperty, binding);

            #endregion

            #region bind cell data

            binding = new Binding();
            {
                binding.Source = cell;
                binding.Mode = BindingMode.TwoWay;
                binding.Path = new PropertyPath("DataContext.[" + cell.Column.DisplayIndex + "]");
            }
            BindingOperations.SetBinding(presenter, EmployeeCellPresenter.CellDataProperty, binding);

            #endregion            
            ...     


public class EmployeeCellData : BaseNotify
    {
        public EmployeeModel Data { get; set; }
        ...
    }