I have this DataGrid
:
<DataGrid x:Name="dgTimeline" Focusable="False" GotFocus="dgTimeline_GotFocus">
So I add columns with a custom class called TimelineControl
and bind its Minutes
properties with Time%
:
for (int i = 0; i <= 30; i++)
{
FrameworkElementFactory fef = new FrameworkElementFactory(typeof(TimelineControl));
Binding bTemp = new Binding("Time" + i);
bTemp.Mode = BindingMode.TwoWay;
fef.SetValue(TimelineControl.MinutesProperty, bTemp);
DataTemplate dt = new DataTemplate();
dt.VisualTree = fef;
dgTempCol.CellTemplate = dt;
dgTimeline.Columns.Add(dgTempCol);
}
Here is TimelineControl
:
public static DependencyProperty MinutesProperty =
DependencyProperty.Register("Minutes", typeof(string), typeof(TimelineControl),
new PropertyMetadata(OnMinutesChanged));
public string Minutes
{
get { return (string)GetValue(MinutesProperty); }
set { SetValue(MinutesProperty, value); }
}
private static void OnMinutesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine("foo bar");
}
Latter on I add some rows with:
TimeScale temp;
temp = this.addEvent(temp, 23);
temp = this.addEvent(temp, 24);
temp = this.addEvent(temp, 25);
temp = this.addEvent(temp, 26);
dgTimeline.Items.Add(temp);
private TimeScale addEvent(TimeScale temp, int time)
{
PropertyInfo propertyInfo = temp.GetType().GetProperty("Time" + (time / 60));
if (propertyInfo.GetValue(temp, null) != null)
{
if (propertyInfo.GetValue(temp, null).ToString().IndexOf((time % 60).ToString()) == -1)
{
propertyInfo.SetValue(temp, Convert.ChangeType(propertyInfo.GetValue(temp, null) +
"," + (time % 60), propertyInfo.PropertyType), null);
}
}
else
{
propertyInfo.SetValue(temp, Convert.ChangeType(time % 60, propertyInfo.PropertyType), null);
}
return temp;
}
Everything works fine so far, the OnMinutesChanged
is triggered just fine and the UI is updated. The problem is that when I try to update something that is on the DataGrid
the OnMinutesChanged
is not triggered and the UI is not updated.
My objective with OnMinutesChanged
is to manually update the UI of the specific elements that were changed. If I call dgTimeline.Items.Refresh()
then the whole grid is refreshed and everything works, the OnMinutesChanged
is called. The problem is that this grid is updated every second, so call dgTimeline.Items.Refresh()
makes the application almost freeze because the number of elements is high (more than 500 easily). I just need to update 3 elements' UI per second, not all the 500, that's why I want to manually do it.
Am I doing the right thing? If yes, why OnMinutesChanged
is not being called when I update the grid?
DataGrid
uses binding groups to validate the whole row and prevent an invalid state in the underlying object in case one of the properties is assigned an invalid value. This changes the default UpdateSourceTrigger
of bindings within cells to Explicit
, you can override this by explicitly setting it to PropertyChanged
on your binding object.
Normally the update is invoked if the user finishes editing a row, you however never enter edit mode as you use CellTemplate
and not CellEditingTemplate
.