Кнопка раскрывающегося меню WPFC#

Место общения программистов C#
Ответить
Anonymous
 Кнопка раскрывающегося меню WPF

Сообщение Anonymous »

Я создал свой собственный элемент управления MenuButton, который выглядит как на скриншоте ниже:
[img]https:/ /i.sstatic.net/oQSQERA4.png[/img]

Итак, пункты меню появляются, когда я нажимаю на кнопку, и скрываются, когда фокус теряется. Обработка кликов по пунктам меню также работает нормально. НО! Только со второго раза! Первый щелчок игнорируется. Я ломаю голову, пытаясь решить эту странную проблему. Может ли кто-нибудь взглянуть на мой код и сказать, где я ошибся?
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:


















Подробнее здесь: https://stackoverflow.com/questions/793 ... enu-button
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»