DropDownButton, command binding failed on itemssource
Describe the bug
With the same model, ItemsSource is bind to an observable collection of ViewModelItem
the first items are working, check is ok and command is called
if items are added after, the command is not called
Steps to reproduce
<mah:DropDownButton Margin="5 5 10 5"
Padding="8"
Content="{DynamicResource DisplayMode.Title}"
DisplayMemberPath="Header"
ItemsSource="{Binding Displays}">
<mah:DropDownButton.Icon>
<mah:PathIcon Width="18"
Height="18"
Margin="6"
Data="M9,6H5V10H7V8H9M19,10H17V12H15V14H19M21,16H3V4H21M21,2H3C1.89,2 1,2.89 1,4V16A2,2 0 0,0 3,18H10V20H8V22H16V20H14V18H21A2,2 0 0,0 23,16V4C23,2.89 22.1,2 21,2" />
</mah:DropDownButton.Icon>
<mah:DropDownButton.ItemContainerStyle>
<Style BasedOn="{StaticResource {x:Type MenuItem}}"
TargetType="{x:Type MenuItem}">
<Setter Property="Command"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mah:DropDownButton}}, Path=DataContext.ChangeDisplayModeCommand}" />
<Setter Property="CommandParameter"
Value="{Binding Mode}" />
<Setter Property="IsCheckable"
Value="True" />
<Setter Property="IsChecked"
Value="{Binding IsSelected}" />
</Style>
</mah:DropDownButton.ItemContainerStyle>
</mah:DropDownButton>
then start
Displays.Add(new DisplayModeItem() { Mode = DisplayMode.Pictogramme, IsSelected = true, Header = StringManager.Instance.GetString("DisplayMode.Picto") });
Displays.Add(new DisplayModeItem() { Mode = DisplayMode.Grid, Header = StringManager.Instance.GetString("DisplayMode.Grid") });
Displays.Add(new DisplayModeItem() { Mode = DisplayMode.Platform, Header = StringManager.Instance.GetString("DisplayMode.Platform") });
Display = DisplayMode.Pictogramme;
after another event add some items
plans.ForEach(p=> Displays.Add( new DisplayModeItem() { Header = p.Name, Mode = DisplayMode.Map, Tag = p } ) );
checking these items is not calling the command
but the IsSelected changed and the binding below works
<Setter Property="IsChecked"
Value="{Binding IsSelected}" />
Environment
MahApps.Metro version: last
Target Framework: .Net Core 8
How is ViewModelItem defined?
i don't think it's relevant because the command is in the parent.. ChangeDisplayModeCommand item is like that
` public partial class DisplayModeItem : ObservableObject { public DisplayMode Mode { get; set; }
[ObservableProperty]
public bool isVisible = true;
[ObservableProperty]
public bool isSelected = false;
partial void OnIsSelectedChanged(bool value)
{
if(value)
{
StrongReferenceMessenger.Default.Send(new ChangeDisplayMessage(this));
}
}
public string Header { get; set; }
public object Tag { get; set; }
} `
btw i found a workaround by sending a message to the parent when the IsSelected change
DisplayMode, Header and Tag are not observable and thus will not invalidate the command. If you use the MVVM Toolkit, you may need to invalidate the partent command when selection is changed. this is by design for performace reasons and not a bug in MahApps
There is no need for that , theses properties are not involved in the problem. and there no need to invalidate the command because its allways true.
IsSelected is well updated when I click an item
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mah:DropDownButton}}, Path=DataContext.ChangeDisplayModeCommand}" />
the command in the style is not working for added items