WPF-Dropdown-MenüschaltflächeC#

Ein Treffpunkt für C#-Programmierer
Guest
 WPF-Dropdown-Menüschaltfläche

Post by Guest »

Ich habe mein eigenes Steuerelement MenuButton erstellt, das wie im Screenshot unten aussieht:
[img]https:/ /i.sstatic.net/oQSQERA4.png[/img]

Die Menüelemente erscheinen also, wenn ich auf die Schaltfläche klicke, und werden ausgeblendet, wenn der Fokus verloren geht. Der Umgang mit Klicks auf Menüelemente funktioniert ebenfalls einwandfrei. ABER! Erst ab dem zweiten Mal! Der erste Klick ist Ignorieren. Ich zerbreche mir den Kopf, wenn ich versuche, dieses seltsame Problem zu beheben. Kann sich jemand meinen Code ansehen und mir sagen, wo ich falsch lag?

Code: Select all

public partial class MenuButton : Button, INotifyPropertyChanged
{
private readonly ContextMenu Menu;
private SolidColorBrush arrowColor = Brushes.Transparent;

public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(string), typeof(MenuButton), new(string.Empty, new(OnSomeTextPropertyChanged)));

public static readonly DependencyProperty MenuPlacementProperty =
DependencyProperty.Register(nameof(MenuPlacement), typeof(PlacementMode), typeof(MenuButton), new(PlacementMode.Top, new(OnSomeMenuPlacementPropertyChanged)));

public static readonly DependencyProperty MenuItemsProperty =
DependencyProperty.Register(nameof(MenuItems), typeof(ItemCollection), typeof(MenuButton), new(default(ItemCollection), new(OnSomeMenuItemsPropertyChanged)));

public SolidColorBrush ArrowColor
{
get => arrowColor;
private set
{
arrowColor = value;
OnPropertyChanged(nameof(arrowColor));
}
}

public string Text
{
get => (string)GetValue(TextProperty);
set => SetCurrentValue(TextProperty, value);
}

public PlacementMode MenuPlacement
{
get => (PlacementMode)GetValue(MenuPlacementProperty);
set => SetCurrentValue(MenuPlacementProperty, value);
}

public ItemCollection MenuItems
{
get => (ItemCollection)GetValue(MenuItemsProperty);
set => SetCurrentValue(MenuItemsProperty, value);
}

public MenuButton()
{
Menu = new()
{
StaysOpen = true,
HasDropShadow = false,
PlacementTarget = this,
Placement = MenuPlacement,
ItemsSource = MenuItems,
};

SetCurrentValue(MenuItemsProperty, new DataGrid().Items);

InitializeComponent();
}

public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
PropertyChanged?.Invoke(this, new(prop));
}

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);

Menu.Width = ActualWidth;
Menu.IsOpen = true;
}

private void MenuButtonControl_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (sender is MenuButton button && bool.TryParse(e.NewValue?.ToString(), out bool enabled))
{
button.ArrowColor = enabled ? Brushes.Black : Brushes.DimGray;
}
}

private static void OnSomeTextPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (target is MenuButton menuButton)
{
menuButton.ButtonText.Content = e.NewValue.ToString();
}
}

private static void OnSomeMenuPlacementPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (target is MenuButton menuButton && menuButton.Menu is ContextMenu menu && Enum.TryParse(e.NewValue?.ToString(), true, out PlacementMode placementMode))
{
menu.Placement = placementMode;
}
}

private static void OnSomeMenuItemsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
if (target is MenuButton menuButton && menuButton.Menu is ContextMenu menu && e.NewValue is ItemCollection itemCollection)
{
menu.ItemsSource = itemCollection;
menu.IsOpen = true;
menu.IsOpen = false;
}
}
}
XAML:

Code: Select all
















Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post