Windows Phone Toolkit Context Menu Items have wrong object bound to them when an item is removed and then added

淺唱寂寞╮ 提交于 2019-12-01 19:36:07

The LongListSelector is a virtualized control, which means it instantiates the DataTemplate you specify a fixed number of times (20, I think), and then reuses those Item containers as you scroll down the list, simply moving them around and rebinding their DataContext's. That way, you can have extremely large lists without needing the whole lot to be in the Visual Tree.

The ContextMenu code, at http://phone.codeplex.com/SourceControl/changeset/view/80797#1335947 has the following lines in the OpenPopup() function;

if (ReadLocalValue(DataContextProperty) == DependencyProperty.UnsetValue)
{
    DependencyObject dataContextSource = Owner ?? _rootVisual;
    SetBinding(DataContextProperty, new Binding("DataContext") { Source = dataContextSource });
}

You'll see that there is a bug here because when the virtualized container rebinds the DataContext, it will not get updated on the _rootVisual, since it's assumed the existing DataContext is the right one. The fix would be to change that check to be:

if (ReadLocalValue(DataContextProperty) == DependencyProperty.UnsetValue ||
    (DataContext != dataContextSource.DataContext))
{
    DependencyObject dataContextSource = Owner ?? _rootVisual;
    SetBinding(DataContextProperty, new Binding("DataContext") { Source = dataContextSource });
}

For those like me not wanting to recompile toolkit here is an easy workaround based on pantaloons answer. Simpy add Opened event handler:

<toolkit:ContextMenu Opened="ContextMenu_Opened">
...
</toolkit:ContextMenu>

Event Handler code:

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
{
    var menu = (ContextMenu)sender;
    var owner = (FrameworkElement)menu.Owner;
    if (owner.DataContext != menu.DataContext)
        menu.DataContext = owner.DataContext;

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!