当DataContext更改时立即更新绑定

9

我正在尝试在更改DataContext后立即测量对象,但对象的绑定没有及时更新。以下是我的代码:

// In MeasureOverride(Size)
m_inputWidth = 0.0;

Size elemSize = new Size(double.PositiveInfinity, RowHeight);
MapElementView ruler = new MapElementView();

// Measure inputs
foreach (MapElementViewModel elem in m_vm.InputElements)
{
   ruler.DataContext = elem;
   ruler.Measure(elemSize);
   m_inputWidth = Math.Max(m_inputWidth, ruler.DesiredSize.Width);
}

我希望能够更新View对象的绑定,以便我可以测量显示ViewModel所需的View的大小。我正在重用相同的View进行测量,因为我正在虚拟化数据。
有人知道如何在DataContext更改时强制更新绑定吗?
请注意,绑定最终会更新。
View包含一个TextBlock,它是基于ViewModel更改大小的主要元素。我在更改DataContext后立即查看了该元素的TextProperty的BindingExpression,但调用UpdateTarget()并不能解决问题,BindingExpression.DataItem似乎为空。
编辑:BindingExression的状态为Unattached。关键是弄清楚如何将其附加。
1个回答

6

如果在设置DataContext后,您按照DataBind优先级在Dispatcher上执行Invoke,则应导致它们全部更新。

由于此代码在MeasureOverride方法内执行,因此无法在Dispatcher上执行Invoke。相反,我会设置一个指示是否已测量标尺宽度的标志,如果没有,请对计算这些宽度的方法进行BeginInvoke。然后,在计算宽度时,调用InvalidateMeasure以强制进行第二次布局传递。

每当其中一个宽度更改时,这将需要额外的布局传递。每当必须重新测量文本框时,您需要将标志重置为false。

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();
}

我遇到了以下异常:无法在挂起调度程序处理时执行此操作。看起来WPF在布局期间锁定了Dispatcher。我正在MeasureOverride()方法中运行此代码。 - Josh G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接