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; }
...
}