2015-06-08 13 views
6

ho una barra degli strumenti con 3 DataTemplates per Mie:ObservableCollection.CollectionChanged non selezionare il DataTemplate corretta sul ToolBar

<ToolBar ItemsSource="{Binding ContextActions}" Background="Transparent" ToolBarTray.IsLocked="True"> 
     <ToolBar.Resources> 
      <DataTemplate DataType="{x:Type viewModels:SimpleContextActionViewModel}"> 
       <Button Command="{Binding ActionCommand}" Style="{StaticResource ToolBarButtonStyle}" ToolTip="{userInterface:Translation Binding={Binding ToolTip}}"> 
        <ContentControl Template="{Binding Icon,Converter={StaticResource NameToResourceConverter}}" Margin="5" /> 
       </Button> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type viewModels:SeparatorViewModel}"> 
       <Rectangle Fill="{StaticResource SeparatorBrush}" Width="1" VerticalAlignment="Stretch" Margin="2,7" /> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type viewModels:PopupContextActionViewModel}"> 
       <Grid> 
        <ToggleButton IsChecked="{Binding ElementName=ContextActionPopup, Mode=TwoWay,Path=IsOpen}" Style="{StaticResource ToolBarButtonStyle}" 
            ToolTip="{userInterface:Translation Binding={Binding ToolTip}}"> 
         <ContentControl Template="{Binding Icon, Converter={StaticResource NameToResourceConverter}}" Margin="5" /> 
        </ToggleButton> 
        <Popup Name="ContextActionPopup" Height="150" Width="150" StaysOpen="False"> 
         <Border BorderBrush="{StaticResource PopupBorderBrush}" BorderThickness="1" Background="White"> 
          <ContentControl userInterface:RegionHelper.RegionName="{Binding RegionId}" /> 
         </Border> 
        </Popup> 
       </Grid> 
      </DataTemplate> 
     </ToolBar.Resources> 
    </ToolBar> 

L'ItemsSource è un ObservableCollection <oggetto>

I primi tre elementi sono già disponibile nel costruttore del mio ViewModel, quei tre usano i DataTemplates come previsto.

Se aggiungo un altro "SimpleContextActionViewModel" a ObservableCollection, la barra degli strumenti aggiunge solo un ContentPresenter che chiama ToString. Se posso aggiungere la seguente riga alla reasign l'ObservableCollection ad uno nuovo, tutto funziona bene:

this.ContextActions = new ObservableCollection<object>(this.ContextActions); 

questo innesca l'attuazione NotifyPropertyChanged del mio ViewModel e tutti gli articoli sono ricreati e guardare bene.

Perché un CollectionChanged della mia ObservableCollection non seleziona un DataTemplate valido mentre PropertyChanged lo fa ?.

Questo è come appare This is how it looks

risposta

3

Ho visto questo accadere prima con la barra degli strumenti quando utilizzato con la raccolta che viene modificata in un punto diverso dal costruttore.

Invece di aggiungere i modelli di dati nelle risorse della barra degli strumenti, aggiungili all'app.xaml e vedrai che il tuo codice funzionerà come dovrebbe. Prova questo e fammi sapere se non funziona ancora

+0

Lo proverò domani, anche se sembra davvero sporco gestire così modelli di dati specifici a livello di applicazione. – Console

+0

@Console non è sicuro del motivo per cui l'approccio standard non funziona. Mi sono imbattuto in questo qualche tempo fa. Se vuoi una soluzione diversa, puoi provare ad implementare un ItemTemplateSelector e vedere se è possibile assegnare DataTemplates in questo modo? – Krishna

1

io non sono sicuro se questo vale nel tuo caso, ma il problema sembra molto simile a: Wiring up CollectionChanged and PropertyChanged (Or : Why do some WPF Bindings not refresh?)

Dalla risposta accettata su quel link:

Se non si fornisce a WPF un modello per un elemento di dati (come gli oggetti Person nell'elenco), verrà utilizzato il metodo ToString() t o display. Questo è un membro, non una proprietà e quindi non ricevi nessuna notifica di evento quando il valore cambia.

Se si aggiunge DisplayMemberPath = "Nome" al tuo casella di riepilogo, sarà generare un modello che si lega correttamente al nome della tua persona - che sarà quindi aggiornare automaticamente come ci si aspetterebbe.

È possibile applicare un DisplayMemberPath alla casella degli strumenti in modo che non utilizzi ToString() per impostazione predefinita per il rendering, ma che invece attivi NotifyPropertyChanged?

+0

Non penso che questo si riferisca al mio esempio, ho definito un DataTemplate per visualizzare i miei dati e funziona come previsto per alcuni elementi. Non è necessario utilizzare DisplayMemberPath se si definisce un DataTemplate su come visualizzare una classe. E non è possibile ottenere ciò che voglio con un percorso membro di visualizzazione. – Console

Problemi correlati