ObservableCollection.CollectionChanged does not select the correct DataTemplate on the ToolBar

I have a ToolBar with 3 DataTemplates for my elements:

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

The ItemsSource element is an ObservableCollection <object>

The first three elements are already available in the constructor of my ViewModel, the three use DataTemplates as expected.

If I add another "SimpleContextActionViewModel" to the ObservableCollection, the ToolBar will add a ContentPresenter that calls ToString. If I add the following line to translate the ObservableCollection to a new one, everything will be fine:

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

this initiates the NotifyPropertyChanged implementation of my ViewModel, and all the elements are recreated and look normal.

Why doesn't the CollectionChanged of my ObservableCollection select a valid DataTemplate, but does the PropertyChanged ?.

This is how it looks This is how it looks

+6
source share
2 answers

I saw this before with the toolbar when used with modifying a collection anywhere except the constructor.

Instead of adding your data templates to the toolbar resources, add them to app.xaml, then you will see that your code will work as it should. Try this and let me know if it still does not work.

+3
source

I'm not sure if this applies in your case, but your problem seems surprisingly similar to: CollectionChanged and PropertyChanged wiring (or: why are some WPF bindings not updated?)

From the accepted answer at this link:

If WPF does not provide a template for the data item (for example, Person objects in your list), the ToString () method will be used by default for display. This is a member, not a property, and therefore you do not receive an event notification when a value changes.

If you add DisplayMemberPath = "Name" to your list, it will generate a template that correctly associates with the name of your face - which will then be updated automatically, as you would expect.

Could you apply DisplayMemberPath to the toolbar so that it doesn't use ToString () by default for rendering, but rather run NotifyPropertyChanged?

+1
source

Source: https://habr.com/ru/post/988728/


All Articles