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.
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);
}
}
CodePudding user response:
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"/>