Ho visto questa domanda posta numerose volte e ho ripassato il mio codice più e più volte. Ma quando assegno alla mia proprietà SelectedItem
-bound con un oggetto, esso non aggiorna l'elemento selezionato dello schermo. Sembra che il ListBox
pensi che l'oggetto che assegno non sia un membro dei suoi articoli.ListBox TwoWay bind to SelectedItem
public class MainViewModel : ViewModelBase
{
//...
public SortedObservableCollection<TubeViewModel> Items { get; private set; }
public TubeViewModel SelectedTube { //get, set, propertychanged, etc. }
}
<ListBox x:Name="TubeList"
Margin="10"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource TubeTemplate}"
SelectedItem="{Binding SelectedTube, Mode=TwoWay}"
SelectionMode="Single"
VirtualizingStackPanel.IsVirtualizing="False">
</ListBox>
Ecco l'impl da uno dei luoghi in cui cerco di impostare SelectedTube
- sicuramente si verifica sul thread principale.
var match =
from t in Items
where t.Model.DataFileName == filename
select t;
if (match.Any())
SelectedTube = match.First();
stavo notando che il SelectedTube
non è mai stato messo in evidenza a meno che non ho cliccato manualmente su di esso, ma tipo di ignorato. Ma poi ho voluto ScrollIntoViewCentered l'elemento selezionato, quindi ho aggiunto un DependencyProperty
a mio avviso per vedere le modifiche di SelectedItem
. Il gestore inizialmente sembrava così:
private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (TubeList.SelectedItem == null)
return;
TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
Ma non ha funzionato se ho impostato il SelectedItem
attraverso il mio legame. Dopo aver deciso che volevo scorrere solo se non fosse sullo schermo, ho cambiato il codice a questo:
private void OnSelectedItemChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (TubeList.SelectedItem == null)
return;
var container = TubeList.ItemContainerGenerator.ContainerFromItem(TubeList.SelectedItem) as FrameworkElement;
if(!container.IsVisible)
TubeList.ScrollIntoViewCentered(TubeList.SelectedItem);
}
Se SelectedItem
è impostato esternamente, il contenitore è nullo. Ogni volta. Ho anche aggiunto il codice per verificare la presenza di null e quindi scorrere lo ItemsSource
alla ricerca di una corrispondenza di nome file, quindi aggiornare SelectedItem
per assicurarmi che SelectedItem
fosse sicuramente un oggetto nella casella di riepilogo. Senza fortuna.
Non è una visibilità, se l'elemento è sullo schermo, non viene evidenziato. Devo implementare una sorta di funzione di uguaglianza? Ho perso più tempo di quanto si possa pensare possibile su questo.
grazie.
Non sono riuscito a riprodurre ciò con quello che vediamo del codice. Ho creato una classe fittizia per TubeViewModel e ho utilizzato tutto il codice pubblicato e ha funzionato come previsto. Qualcosa deve succedere altrove. –
Grazie mille, Ben e Kent. Sono in vacanza per un po ', questo dovrà aspettare. – Thomas