Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Multibinding Converter not called in ItemsControl

When SelectedItem value changes it does not trigger SelectedItemConverter.

I tried to use SetCurrentValue and InvalidateProperty and fiddled with attributes like
NotifyOnSourceUpdated, UpdateSourceTrigger and Mode.

Sadly they do not work.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Perhaps I should add something in parent xaml to nudge it?
Currently its:

   <local:Menu
            SelectedItem="{Binding SelectedMenuItem}"
            OnSelect="{Binding OnSelectCommand}" Items="{Binding MenuItems}"/>

Thanks for help.

control xaml

<UserControl>
 <UserControl.Resources>
        <vm:MockMenuViewModel x:Key="DesignViewModel"/>
        <cv:SelectedItemConverter x:Key="SelectedItemConverter"/>
    </UserControl.Resources>
    <ItemsControl
        d:DataContext="{Binding Source={StaticResource DesignViewModel}}"
        ItemsSource="{Binding Path=MenuItems, Mode=OneWay}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel></StackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type MenuItem}">
                <Button Content="{Binding Name}"
                        Command="{Binding OnSelect, RelativeSource={RelativeSource AncestorType=UserControl}}"
                        CommandParameter="{Binding}">
                    <Button.IsEnabled>
                        <MultiBinding Converter="{StaticResource SelectedItemConverter}"
                                      NotifyOnSourceUpdated="True"
                                      NotifyOnTargetUpdated="True" Mode="OneWay">
                            <Binding Path="SelectedItem" UpdateSourceTrigger="PropertyChanged" Mode="OneWay"/>
                            <Binding Path="." Mode="OneWay"/>
                        </MultiBinding>
                    </Button.IsEnabled>
                </Button>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>

control cs

 public partial class Menu : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;

        public Menu()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
            "SelectedItem",
            typeof(MenuItem),
            typeof(Menu),
            new PropertyMetadata(null, OnSelectedItemChanged));

        public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
            "Items",
            typeof(IEnumerable<MenuItem>),
            typeof(Menu),
            new FrameworkPropertyMetadata(null));

        public static readonly DependencyProperty OnSelectProperty = DependencyProperty.Register(
            "OnSelect",
            typeof(ICommand),
            typeof(Menu),
            new PropertyMetadata(null, OnSelectChanged));


        public MenuItem SelectedItem
        {
            get => (MenuItem)GetValue(SelectedItemProperty);
            set
            {
                SetValue(SelectedItemProperty, value);
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Items)));
            }
        }

        public IEnumerable<MenuItem> Items
        {
            get => (IEnumerable<MenuItem>)GetValue(ItemsProperty);
            set => SetValue(ItemsProperty, value);
        }

        public ICommand OnSelect
        {
            get => (ICommand)GetValue(OnSelectProperty);
            set => SetValue(OnSelectProperty, value);
        }

        public static void OnSelectedItemChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            var menu = dependencyObject as Menu;

            if (menu == null)
            {
                return;
            }

            menu.InvalidateProperty(SelectedItemProperty);
            menu.InvalidateProperty(ItemsProperty);
        }

        public static void OnSelectChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
        {
            var menu = dependencyObject as Menu;

            if (menu == null)
            {
                return;
            }

            menu.SetCurrentValue(OnSelectProperty, eventArgs.NewValue);
        }
    }

>Solution :

If you are trying to bind to the SelectedItem property of the parent Menu UserControl, you should specify a RelativeSource:

<Binding Path="SelectedItem"
    RelativeSource="{RelativeSource AncestorType=UserControl}"
    UpdateSourceTrigger="PropertyChanged" Mode="OneWay"/>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading