Reputation: 123
I have a datagrid with 3 DataGridTextColumns
<DataGrid.Columns>
<DataGridTextColumn Header="Field Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn x:Name="BeginFields" Header="Begin" Binding="{Binding Begin, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn x:Name="LengthFields" Header="Length" Binding="{Binding Length, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataGrid.Columns>
All three DataGridTextColumns data gets added into an ObservableCollection. I iterate through the collection to get an instance, and set the values for the next row.
The program needs to Update accordingly if any of the fields get updated.
Right now I can only manipulate the Beginning field, but not the Length Field.
Think of the beginning field as a line in the text document, and the length field as the next line in a text document, these two fields must be perfectly apart and never overlap each other, I hope I made sense in what I am trying to accomplish I am fairly new to programming and my algorithm skills are not potent. Please assist me , If something I said does not make sense please let me know I will elaborate as best as I can. See Code for more details.
Thank you!!
I will now past the Code behind
public MainWindow()
{
InitializeComponent();
dataGrid.ItemsSource = MWVM.FieldsCollection;
fileButton.Click += FileButton_Click;
loadPresetButton.Click += LoadPresetButton_Click;
savePresetButton.Click += SavePresetButton_Click;
clipboardButton.Click += ClipboardButton_Click;
saveButton.Click += SaveButton_Click;
****dataGrid.SelectedCellsChanged += ((o, e) =>
{
int track = 0;
foreach (Field f in MWVM.FieldsCollection)
{
track += f.Length;
f.Begin = track - f.Length;
}
}); ****
}
public class Field : ViewModelsBase
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
private int _begin;
public int Begin
{
get
{
return _begin;
}
set
{
if (value != _begin)
{
_begin = value;
RaisePropertyChanged("Begin");
}
}
}
private int _length;
public int Length
{
get { return _length; }
set
{
if (value != _length)
{
_length = value;
RaisePropertyChanged("Length");
}
}
}
[JsonIgnore]
public string Blank { get; set; } = "";
}
public class MainWindowViewModel : ViewModelsBase
{
public ObservableCollection<Field> fieldsCollection;
public MainWindowViewModel()
{
_fields = CreateFieldsCollection();
}
private ObservableCollection<Field> CreateFieldsCollection()
{
fieldsCollection = new ObservableCollection<Field>();
return fieldsCollection;
}
ObservableCollection<Field> _fields;
public ObservableCollection<Field> FieldsCollection
{
get
{
return _fields;
}
set
{
if (_fields != value)
{
_fields = value;
RaisePropertyChanged("FieldsCollection");
}
}
}
}
Upvotes: 0
Views: 483
Reputation: 169200
You should handle this logic in your view model class.
You could handle the PropertyChanged
event of each Field
object that is added to the ObservableCollection<Field>
and recalculate the Begin and Length fields accordingly. Please refer to the following sample code which should give you the idea:
public class MainWindowViewModel : ViewModelsBase
{
public MainWindowViewModel()
{
_fields = CreateFieldsCollection();
_fields.CollectionChanged += _fields_CollectionChanged;
}
private ObservableCollection<Field> CreateFieldsCollection()
{
ObservableCollection<Field> fieldsCollection = new ObservableCollection<Field>();
fieldsCollection.Add(new Field() { Begin = 0, Length = 5 });
fieldsCollection.Add(new Field() { Begin = 5, Length = 5 });
fieldsCollection.Add(new Field() { Begin = 10, Length = 5 });
fieldsCollection.Add(new Field() { Begin = 15, Length = 5 });
fieldsCollection.Add(new Field() { Begin = 20, Length = 5 });
foreach (Field field in fieldsCollection)
field.PropertyChanged += item_PropertyChanged;
return fieldsCollection;
}
private void _fields_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (object field in e.NewItems)
{
(field as INotifyPropertyChanged).PropertyChanged
+= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
if (e.OldItems != null)
{
foreach (object country in e.OldItems)
{
(country as INotifyPropertyChanged).PropertyChanged
-= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (_fields.Count < 2)
return;
switch(e.PropertyName)
{
case "Length":
//recalculate the begin of each field
RecalculateBegin();
break;
case "Begin":
Field modifiedField = sender as Field;
int indexOfModifiedField = FieldsCollection.IndexOf(modifiedField);
if(indexOfModifiedField > 0)
{
//recalculate the length of the previous field:
Field previousField = FieldsCollection[indexOfModifiedField - 1];
previousField.Length = modifiedField.Begin - previousField.Begin;
}
//...and the recalculate the begin of the rest of the fields:
RecalculateBegin();
break;
}
}
private void RecalculateBegin()
{
int length = _fields[0].Begin + _fields[0].Length;
for (int i = 1; i < FieldsCollection.Count; ++i)
{
FieldsCollection[i].Begin = length;
length += FieldsCollection[i].Length;
}
}
private ObservableCollection<Field> _fields;
public ObservableCollection<Field> FieldsCollection
{
get { return _fields; }
set
{
if (_fields != value)
{
_fields = value;
RaisePropertyChanged("FieldsCollection");
}
}
}
}
Upvotes: 1