【问题标题】:Keep submenu open when a new image is selected for display选择新图像进行显示时保持子菜单打开
【发布时间】:2017-10-17 03:25:42
【问题描述】:

使用 WPF: A Simple Color Picker With Preview, Sacha Barber, 18 Apr 2012 , 我从中创建了一个自定义控件:

public class ColorCustomControl : Control 
{....}

然后用作:

<Menu....>
    <MenuItem.....>
       <pn:ColorCustomControl/>
    </MenuItem>
</Menu>

在选择刷子MenuItem时,它会产生以下图片:

在打开的画笔子菜单中选择任何项目都会导致在画笔子菜单保持打开状态下采取适当的操作。这就是我想要的效果。

但是,如下所示,选择三个色板中的任何一个都会导致新色板快速闪烁——它会替换“预览”左侧的颜色模式——然后立即关闭画笔子菜单。

如果再次选择画笔菜单项,则会正确显示最近选择的样本。

我已经尝试了所有预览事件(即键盘失去焦点、鼠标左键按下等),以尝试在选择样本时停止关闭子菜单。我发现没有任何东西可以阻止弹出窗口关闭。

从视觉中选择样本时,如何防止“画笔”子菜单关闭?

(我强烈怀疑在选择新样本图像时重绘视觉对象,如 InvalidateVisual() 会强制关闭子菜单)。

有什么想法吗?

TIA

【问题讨论】:

  • 我发现this SO answer 使用的是StaysOpenOnClick 你试过这个吗?
  • @XAMlMAX 是的...它不起作用,覆盖 PreviewLostKeyboardFocus 或任何使用 IsSubmenuOpen 的方法也不起作用。即使选择任何其他菜单项不会关闭弹出窗口,在重绘所选样本后,似乎没有什么能保持打开状态。由于这是强制重绘的唯一选择,我怀疑 InvalidateVisual() 正在强制关闭弹出窗口。不确定——也不知道在弹出窗口过早关闭后如何以编程方式重新打开它。

标签: wpf menu custom-controls menuitem


【解决方案1】:

我的建议是停止从您的用户控件传播事件。所以首先在你的ColorCustomControl 类中添加一个属性(如果你需要,它也可以是一个依赖项):

private bool propagateEvents = true;

public bool PropagateEvents
{
    get
    {
        return propagateEvents;
    }
    set
    {
        propagateEvents = value;
    }
}

然后在每个鼠标事件处理程序的末尾添加e.Handled = !PropagateEvents;;最后添加一个Swatch_MouseLeftButtonUp 方法(它必须处理ImgSqaure1ImgSqaure2ImgCircle1 引发的事件)。 结果将是:

private void Swatch_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Image img = (sender as Image);
    ColorImage.Source = img.Source;

    e.Handled = !PropagateEvents;
}

private void Swatch_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    e.Handled = !PropagateEvents;
}

private void CanvImage_MouseDown(object sender, MouseButtonEventArgs e)
{
    IsMouseDown = true;
    e.Handled = !PropagateEvents;
}

private void CanvImage_MouseUp(object sender, MouseButtonEventArgs e)
{
    IsMouseDown = false;
    e.Handled = !PropagateEvents;
}

在用户控件 XAML 中:

<Image x:Name="ImgSqaure1" 
        Height="20" Width="20" 
        Source="Images/ColorSwatchSquare1.png" 
        Margin="45,0,0,0" 
        ToolTip="Square swatch1" 
        MouseLeftButtonDown="Swatch_MouseLeftButtonDown"
        MouseLeftButtonUp="Swatch_MouseLeftButtonUp"/>
<Image x:Name="ImgSqaure2" 
        Height="20" Width="20" 
        Source="Images/ColorSwatchSquare2.png" Margin="5,0,0,0" 
        ToolTip="Square swatch2" 
        MouseLeftButtonDown="Swatch_MouseLeftButtonDown"
        MouseLeftButtonUp="Swatch_MouseLeftButtonUp"/>
<Image x:Name="ImgCircle1" Height="20" Width="20" 
        Source="Images/ColorSwatchCircle.png" Margin="5,0,0,0" 
        ToolTip="Circle swatch1" 
        MouseLeftButtonDown="Swatch_MouseLeftButtonDown"
        MouseLeftButtonUp="Swatch_MouseLeftButtonUp" />

现在您所要做的就是在菜单中设置PropagateEvents 属性:

<Menu....>
    <MenuItem.....>
       <pn:ColorCustomControl PropagateEvents="False" />
    </MenuItem>
</Menu>

希望对你有帮助。

【讨论】:

  • 谢谢。那行得通!我之前尝试过,但我只标记了 MouseLeftButtonDown 事件——而不是 Down 和 Up 事件。如果仅将 MouseLeftButtonDown 事件标记为已处理,则此操作失败。将 Down 和 Up 事件标记为在 Swatch 上处理就可以了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
相关资源
最近更新 更多