I am trying to measure an object immediately after changing the DataContext, but the binding for the object is not getting updated soon enough. Here\'s my code:
Well, if after setting the DataContext, you did an Invoke on the Dispatcher at the DataBind priority, it should cause them all to be updated.
Since this code is being executed inside the MeasureOverride method, you can't do an Invoke on the Dispatcher. Instead, I would make a flag that indicated if the ruler width had been measured, and if not, do a BeginInvoke on the method that calculates those widths. Then, when the widths are calculated, call InvalidateMeasure to force a second layout pass.
This is going to require an additional layout pass every time one of those widths changes. You will need to reset the flag to false whenever the textboxes have to be remeasured.
private bool isRulerWidthValid = false;
protected override Size MeasureOverride(Size available)
{
... // other code for measuring
if (!isRulerWidthValid)
{
Dispatcher.BeginInvoke(new Action(CalculateRulerSize));
... // return some temporary value here
}
... // do your normal measure logic
}
private void CalculateRulerSize(Size available)
{
Size elemSize = new Size(double.PositiveInfinity, RowHeight);
m_inputWidth = 0.0;
foreach (MapElementViewModel elem in m_vm.InputElements)
{
ruler.DataContext = elem;
ruler.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.DataBind);
ruler.Measure(elemSize);
m_inputWidth = Math.Max(m_inputWidth, ruler.DesiredSize.Width);
}
// invalidate measure again, as we now have a value for m_inputwidth
isRulerWidthValid = true;
InvalidateMeasure();
}