I have a custom control I have set up in c#/wpf. I am using Dependency properties for items, some of these are optional, but my current code seems very convoluted:
public class PopupMenu : ContentControl
{
public static readonly DependencyProperty AddWordCommandProperty =
DependencyProperty.Register(nameof(AddWordCommand), typeof(ICommand), typeof(PopupMenu),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnAddWordCommandChanged));
public static readonly DependencyProperty ShowAddWordButtonProperty =
DependencyProperty.Register(nameof(ShowAddWordButton), typeof(bool), typeof(PopupMenu),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnShowAddWordButtonChanged));
public ICommand AddWordCommand
{
get => (ICommand)GetValue(AddWordCommandProperty);
set => SetValue(AddWordCommandProperty, value);
}
public bool ShowAddWordButton
{
get => (bool)GetValue(ShowAddWordButtonProperty);
set => SetValue(ShowAddWordButtonProperty, value);
}
private static void OnAddWordCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not PopupMenu ctrl)
return;
ctrl.AddWordCommand = (ICommand)e.NewValue;
}
private static void OnShowAddWordButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not PopupMenu ctrl)
return;
ctrl.ShowAddWordButton = (bool)e.NewValue;
}
}
When I use this control I must pass a command and also a bool for this button.
I have tried (and failed) ways of not having to pass the bool and instead letting 'ShowAddWordButton' be self-calculating, but is there a correct way to deal with this?
Attempt 1 - failed:
public ICommand AddWordCommand
{
get => (ICommand)GetValue(AddWordCommandProperty);
set
{
SetValue(AddWordCommandProperty, value);
SetValue(ShowAddWordButtonProperty, value != null);
}
}
Attempt 2 - Failed:
private static void OnAddWordCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not PopupMenu ctrl)
return;
var cmd = (ICommand)e.NewValue;
ctrl.AddWordCommand = cmd;
ctrl.ShowAddWordButton = cmd != null;
}
I have this code in place as this menu is going to grow with more buttons and they will not always be shown.
TIA
You haven't clearly stated what you want to get. I hope my guess is correct and this code will help you.
public class PopupMenu : ContentControl
{
public static readonly DependencyProperty AddWordCommandProperty =
DependencyProperty.Register(nameof(AddWordCommand), typeof(ICommand), typeof(PopupMenu),
new FrameworkPropertyMetadata(null,
(d,e)=> d.SetValue(ShowAddWordButtonPropertyKey, e.NewValue is not null)));
private static readonly DependencyPropertyKey ShowAddWordButtonPropertyKey =
DependencyProperty.RegisterReadOnly(nameof(ShowAddWordButton), typeof(bool), typeof(PopupMenu),
new FrameworkPropertyMetadata(false));
public static readonly DependencyProperty ShowAddWordButtonProperty = ShowAddWordButtonPropertyKey.DependencyProperty;
public ICommand AddWordCommand
{
get => (ICommand)GetValue(AddWordCommandProperty);
set => SetValue(AddWordCommandProperty, value);
}
public bool ShowAddWordButton => (bool)GetValue(ShowAddWordButtonProperty);
}
Implementation option using style triggers:
<Style TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="Command" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>