DataTemplate中的ContextMenu绑定问题
本文关键字:问题 绑定 ContextMenu 中的 DataTemplate | 更新日期: 2023-09-27 17:54:49
在LongListSelector中有一个上下文菜单。此列表在运行时创建和更新。
<phone:PanoramaItem Header="{Binding Path=LocalizedResources.SavedGamesHeader, Source={StaticResource LocalizedStrings}}" Orientation="Horizontal">
<phone:LongListSelector Margin="0,0,-22,2" ItemsSource="{Binding SavedGames}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="12,2,0,20" Width="432">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Remove" Click="RemoveSave_OnClick"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Image Margin="10,5,10,0" Height="173" Width="248" Source="{Binding Screen}" Stretch="Fill" HorizontalAlignment="Left"></Image>
<StackPanel Width="311" Margin="8,5,0,0" HorizontalAlignment="Left">
<TextBlock Tap="Save_OnTap" Tag="{Binding SavedGame}" Text="{Binding SaveName}" TextWrapping="Wrap" Margin="10,0" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeMedium}" Foreground="White" FontWeight="Bold" FontFamily="Arial Black" HorizontalAlignment="Left" />
<TextBlock Text="{Binding GameName}" TextWrapping="Wrap" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Left" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Text="Created on:" Margin="10,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
<TextBlock Text="{Binding Created}" TextWrapping="Wrap" Margin="5,-2,10,0" Style="{StaticResource PhoneTextSubtleStyle}" />
</StackPanel>
</StackPanel>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</phone:PanoramaItem>
下面是处理菜单项点击事件的方法
private void RemoveSave_OnClick(object sender, RoutedEventArgs e)
{
var menuItem = (MenuItem)sender;
var saveViewModel = menuItem.DataContext as SavesViewModel;
EmuStorageMgr.Instance.DeleteSave(saveViewModel.SavedGame.SaveFolder);
App.ViewModel.RescanSaves();
}
下面的方法填充SavedGames列表
public ObservableCollection<SavesViewModel> SavedGames { get; private set; }
public void RescanSaves()
{
SavedGames.Clear();
var saves = EmuStorageMgr.Instance.GetSaves();
foreach (var save in saves)
{
SavedGames.Add(new SavesViewModel(save));
}
this.IsSavesLoaded = true;
NotifyPropertyChanged("SavedGames");
}
所以,当SavedGames收集第一次流行时,它工作得很好,但当收集改变时(删除一些旧物品,添加新物品),我观察到一些奇怪的行为。当OnClick事件被触发时,我看到menuItem。DataContext不是用于我单击的菜单项,而是用于一些已删除的旧菜单项。
我不能在你的帖子下留言,所以我在这里写上:
这是一个已知的问题,我也有一个。我还没有找到任何方法来完全解决这个问题,也没有看到任何最近的解决方案。你可以看到我在这里的帖子,以确保问题与你的一致。
到目前为止我看到的唯一解决方案是在2011年的msdn博客中描述的。它确定了Silverlight框架中的问题,并提供了一个解决方案,我实现了这个解决方案。在项目中包含类文件并使用XAML标记,这样就可以使上下文菜单与父类的数据上下文保持同步。我使用它时遇到了一个小副作用,所以它只是一个创可贴。
我还从另一个论坛上发现,这是一个已知的问题,没有解决方案,但在codeplex这里可以找到一个补丁。我对补丁的问题是我不知道如何实现它,而且LLS(这就是我使用的ContextMenu)已经直接迁移到SDK中,所以我被卡住了。
这就是我对这个问题的全部了解,希望能有所帮助。如果其他人还有什么要补充的,请补充。更新:使用上面提供的链接中的一些内容,我认为我有一个稍微更好的解决方案。在ContextMenu Unloaded事件中刷新视图。比如:
private void add_but_up(object sender, RoutedEventArgs e)
{
ContextMenu conmen = (sender as ContextMenu);
conmen.ClearValue(FrameworkElement.DataContextProperty);
}
这基本上就是博客中的补丁所做的。只是在完全不同的背景下。所以我的问题是无法使用像ScrollTo()这样的函数。在实际页面后面的代码中这样做似乎修复了ContextMenu绑定问题。