ContextMenu IsOpen 属性 始终为 false
ContextMenu IsOpen property is always false
我有一个 ContextMenu
设置如下的按钮:
<Button
x:Name="TestButton"
Click="TestButton_Click">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Sample Menu Item 1" />
<MenuItem Header="Sample Menu Item 2" />
<MenuItem Header="Sample Menu Item 3" />
</ContextMenu>
</Button.ContextMenu>
</Button>
后面的代码:
private void TestButton_Click(object sender, RoutedEventArgs e)
{
// This always prints false, even though the contextmenu is currently opened
System.Console.WriteLine(button.ContextMenu.IsOpen);
if (sender is Button button)
{
button.ContextMenu.Placement = PlacementMode.Bottom;
button.ContextMenu.PlacementTarget = button;
button.ContextMenu.StaysOpen = true;
button.ContextMenu.IsOpen = !button.ContextMenu.IsOpen; // Doesn't work!
}
}
所以我已将 ContextMenu
设置为单击鼠标即可打开并且有效,但是我想在每次单击按钮时切换 ContextMenu
可见性。为此,我想使用 IsOpen
属性 - 如果当前值为真,则将其设置为假,反之亦然。
我的问题是,即使 IsOpen
属性 值在第一次点击时从 false
设置为 true
,它始终保持 false
在第二次点击时,就像它永远不会被设置一样。
我认为这是关于失去焦点(如果我错了请纠正我)- 那么我怎样才能解决这个问题并将其标记为打开状态,直到发生另一次点击?
试试这个。
private bool _isOpen = false;
private void TestButton_Click(object sender, RoutedEventArgs e)
{
// This always prints false, even though the contextmenu is currently opened
//System.Console.WriteLine(button.ContextMenu.IsOpen);
if (sender is Button button)
{
if (_isOpen)
{
button.ContextMenu.IsOpen = false;
_isOpen = false;
}
else
{
button.ContextMenu.Placement = PlacementMode.Bottom;
button.ContextMenu.PlacementTarget = button;
button.ContextMenu.StaysOpen = true;
_isOpen = true;
button.ContextMenu.IsOpen = _isOpen;
}
}
}
I assume it's about the losing focus ...
是的,ContextMenu
的 StaysOpen
属性 没有像您预期的那样工作。当您点击 Button
时,ContextMenu
确实关闭了。
您可以通过使用跟踪 ContextMenu
何时关闭的 DependencyPropertyDescriptor
解决此问题,然后将经过的时间与事件处理程序中的某个常量值进行比较。这应该有效:
private DependencyPropertyDescriptor _dpd;
private DateTime _closeTime;
private void TestButton_Click(object sender, RoutedEventArgs e)
{
if (sender is Button button)
{
button.ContextMenu.Placement = PlacementMode.Bottom;
button.ContextMenu.PlacementTarget = button;
button.ContextMenu.IsOpen = !button.ContextMenu.IsOpen && DateTime.UtcNow.Subtract(_closeTime).TotalMilliseconds > 250;
if (_dpd == null)
{
_dpd = DependencyPropertyDescriptor.FromProperty(ContextMenu.IsOpenProperty, typeof(ContextMenu));
_dpd.AddValueChanged(button.ContextMenu, OnContextMenuClosed);
}
}
}
private void OnContextMenuClosed(object sender, EventArgs e) => _closeTime = DateTime.UtcNow;
我有一个 ContextMenu
设置如下的按钮:
<Button
x:Name="TestButton"
Click="TestButton_Click">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Sample Menu Item 1" />
<MenuItem Header="Sample Menu Item 2" />
<MenuItem Header="Sample Menu Item 3" />
</ContextMenu>
</Button.ContextMenu>
</Button>
后面的代码:
private void TestButton_Click(object sender, RoutedEventArgs e)
{
// This always prints false, even though the contextmenu is currently opened
System.Console.WriteLine(button.ContextMenu.IsOpen);
if (sender is Button button)
{
button.ContextMenu.Placement = PlacementMode.Bottom;
button.ContextMenu.PlacementTarget = button;
button.ContextMenu.StaysOpen = true;
button.ContextMenu.IsOpen = !button.ContextMenu.IsOpen; // Doesn't work!
}
}
所以我已将 ContextMenu
设置为单击鼠标即可打开并且有效,但是我想在每次单击按钮时切换 ContextMenu
可见性。为此,我想使用 IsOpen
属性 - 如果当前值为真,则将其设置为假,反之亦然。
我的问题是,即使 IsOpen
属性 值在第一次点击时从 false
设置为 true
,它始终保持 false
在第二次点击时,就像它永远不会被设置一样。
我认为这是关于失去焦点(如果我错了请纠正我)- 那么我怎样才能解决这个问题并将其标记为打开状态,直到发生另一次点击?
试试这个。
private bool _isOpen = false;
private void TestButton_Click(object sender, RoutedEventArgs e)
{
// This always prints false, even though the contextmenu is currently opened
//System.Console.WriteLine(button.ContextMenu.IsOpen);
if (sender is Button button)
{
if (_isOpen)
{
button.ContextMenu.IsOpen = false;
_isOpen = false;
}
else
{
button.ContextMenu.Placement = PlacementMode.Bottom;
button.ContextMenu.PlacementTarget = button;
button.ContextMenu.StaysOpen = true;
_isOpen = true;
button.ContextMenu.IsOpen = _isOpen;
}
}
}
I assume it's about the losing focus ...
是的,ContextMenu
的 StaysOpen
属性 没有像您预期的那样工作。当您点击 Button
时,ContextMenu
确实关闭了。
您可以通过使用跟踪 ContextMenu
何时关闭的 DependencyPropertyDescriptor
解决此问题,然后将经过的时间与事件处理程序中的某个常量值进行比较。这应该有效:
private DependencyPropertyDescriptor _dpd;
private DateTime _closeTime;
private void TestButton_Click(object sender, RoutedEventArgs e)
{
if (sender is Button button)
{
button.ContextMenu.Placement = PlacementMode.Bottom;
button.ContextMenu.PlacementTarget = button;
button.ContextMenu.IsOpen = !button.ContextMenu.IsOpen && DateTime.UtcNow.Subtract(_closeTime).TotalMilliseconds > 250;
if (_dpd == null)
{
_dpd = DependencyPropertyDescriptor.FromProperty(ContextMenu.IsOpenProperty, typeof(ContextMenu));
_dpd.AddValueChanged(button.ContextMenu, OnContextMenuClosed);
}
}
}
private void OnContextMenuClosed(object sender, EventArgs e) => _closeTime = DateTime.UtcNow;