2013-01-21 20 views
5

Ho un menu di scelta rapida in LongListSelector. Questo elenco viene creato e aggiornato in runtime.ContextMenu in DataTemplate Problema di binding

<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> 

Ecco il metodo che gestisce l'evento click sulla voce di menu

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

Il metodo seguente popola l'elenco 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"); 
    } 

Così, quando la raccolta SavedGames è populaed per la prima volta funziona perfettamente, ma quando le collezioni cambiano (cancella alcuni vecchi oggetti, aggiungi nuovi) osservo un comportamento strano. Quando viene attivato l'evento OnClick, vedo che menuItem.DataContext non è per la voce di menu su cui ho fatto clic ma per alcune vecchie voci di menu che sono state eliminate.

+0

Quando la raccolta cambia, anche le voci del menu? Penso che possa avere qualcosa a che fare con il modo in cui il binding è fatto e una parte non si sta aggiornando. –

+0

ad esempio, RemoveSave_OnClick può rimuovere l'elemento, ogni volta che chiama RescanSaves che cancella la raccolta e la ricompone nuovamente – Shedon

risposta

8

Non posso lasciare un commento su sei post in modo che dirò qui:

Questo è un problema noto e uno che ho anche. Non ho trovato alcun modo per risolvere completamente questo problema e non ho visto nessuna soluzione recente. Puoi vedere il mio post here per accertarti che il problema sia in linea con il tuo.

L'unica soluzione che ho visto finora è descritta qui in un msdn blog from '11. Identifica il problema in Silverlight Framework e fornisce una soluzione alternativa che ho implementato. Includere il file di classe nel progetto e utilizzare i tag XAML e consentirà al proprio menu di contesto di rimanere sincronizzato con il datacontext del genitore. Mi sono imbattuto in un piccolo effetto collaterale che lo utilizza, quindi è solo un cerotto.

Ho anche rilevato da un altro forum che si tratta di un problema noto senza soluzione, ma una patch può essere trovata a codeplex here. Il mio problema con la patch è che non riuscivo a capire come implementarlo, e anche il LLS (che è quello che sto usando il ContextMenu con) è migrato direttamente nell'SDK, quindi sono rimasto bloccato.

Questo è tutto ciò che ho scoperto sul problema, spero che sia d'aiuto. Se qualcun altro ha più da aggiungere, per favore fallo.

Aggiornamento: Utilizzando alcuni dei collegamenti riportati sopra, penso di avere una soluzione leggermente migliore. Nell'evento ContextMenu Unloaded, aggiorna la vista. Qualcosa di simile:

private void add_but_up(object sender, RoutedEventArgs e) 
    { 
     ContextMenu conmen = (sender as ContextMenu); 
     conmen.ClearValue(FrameworkElement.DataContextProperty); 
    } 

Questo è essenzialmente ciò che fa la patch nel blog. Solo in un contesto completamente diverso. Quindi i miei problemi erano l'impossibilità di usare funzioni come ScrollTo(). Facendo questo nel codice retrostante della pagina effettiva sembra corretto il problema di binding di ContextMenu.

Problemi correlati