我有一些麻烦的EventToCommand不表现为我期望与CaptureMouse。

我有已经定义几个EventToCommand对一个ResizeGrip:

<ResizeGrip Name="ResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE">
<i:Interaction.Triggers>
  <i:EventTrigger EventName="MouseLeftButtonDown">
   <cmd:EventToCommand Command="{Binding ResizeStartCommand}" PassEventArgsToCommand="True" />
  </i:EventTrigger>
  <i:EventTrigger EventName="MouseLeftButtonUp">
   <cmd:EventToCommand Command="{Binding ResizeStopCommand}" PassEventArgsToCommand="True" />
  </i:EventTrigger>
  <i:EventTrigger EventName="MouseMove">
   <cmd:EventToCommand Command="{Binding ResizeCommand}" PassEventArgsToCommand="True" />
  </i:EventTrigger>
 </i:Interaction.Triggers>
 </ResizeGrip>

在处理功能被设定为以类的构造函数:

ResizeStartCommand = new RelayCommand<MouseButtonEventArgs>(
    (e) => OnRequestResizeStart(e));
ResizeStopCommand = new RelayCommand<MouseButtonEventArgs>(
    (e) => OnRequestResizeStop(e));
ResizeCommand = new RelayCommand<MouseEventArgs>(
    (e) => OnRequestResize(e),
    param => CanResize);

最后,我尽我的逻辑来调整大小:

void OnRequestResizeStart(MouseButtonEventArgs e)
{
    bool r = Mouse.Capture((UIElement)e.Source);
    Console.WriteLine("mouse down: " + r.ToString());
}
void OnRequestResizeStop(MouseButtonEventArgs e)
{
    ((UIElement)e.Source).ReleaseMouseCapture();
    _canResize = false;
}
void OnRequestResize(MouseEventArgs e)
{
    Console.WriteLine("mouse move");
}
bool CanResize
{ get { return _canResize; } }

在OnRequestResizeStart&OnRequestResizeStop命令做工精细,并且OnRequestResize工作......但只有当我真正是在ResizeGrip。它不会出现该CaptureMouse实际上不发送所有的鼠标事件到ResizeGrip。

这是EventToCommand的限制,或确实发生一些特别的需求?

感谢您的帮助!

有帮助吗?

解决方案

为什么要使用命令为这个而不是标准的事件处理程序?这清楚地是,在代码隐藏属于UI逻辑,而不是一个视图模型。

****更新**

在,你在ControlTemplate中使用此,你可以把控件的为您的后台代码的情况。要做到这些事件的连接,你可以使用TemplatePart模式,连接到OnApplyTemplate特别命名的元素。为了便于将尺寸(或任何其他的虚拟机需要),你可以添加一个DP存储适当的值,并绑定一个虚拟机属性这一点。这也使得做了两路,如果你需要做类似的东西从VM设置的初始大小结合。

// this doesn't enforce the name but suggests it
[TemplatePart(Name = "PART_Resizer", Type = typeof(ResizeGrip))]
public class MyContainer : ContentControl
{
    private ResizeGrip _grip;

    public static readonly DependencyProperty ContainerDimensionsProperty = DependencyProperty.Register(
        "ContainerDimensions",
        typeof(Size),
        typeof(MyContainer),
        new UIPropertyMetadata(Size.Empty, OnContainerDimensionsChanged));

    private static void OnContainerDimensionsChanged(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
    {
        MyContainer myContainer = dObj as MyContainer;
        if (myContainer != null)
        {
            Size newValue = (Size)e.NewValue;
            if (newValue != Size.Empty)
            {
                myContainer.Width = newValue.Width;
                myContainer.Height = newValue.Height;
            }
        }
    }

    public Size ContainerDimensions
    {
        get { return (Size)GetValue(ContainerDimensionsProperty); }
        set { SetValue(ContainerDimensionsProperty, value); }
    }

    static MyContainer()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyContainer), new FrameworkPropertyMetadata(typeof(MyContainer)));
    }

    public override void OnApplyTemplate()
    {
        _grip = Template.FindName("PART_Resizer", this) as ResizeGrip;
        if (_grip != null)
        {
            _grip.MouseLeftButtonDown += Grip_MouseLeftButtonDown;
            // other handlers
        }

        SizeChanged += MyContainer_SizeChanged;
        base.OnApplyTemplate();
    }

    void MyContainer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        // update your DP
    }
    ...
}

要充分利用这一点,你需要确保你在正确的类型和名称相匹配的属性模板有一个元素。

<local:MyContainer ContainerDimensions="{Binding Path=SavedSize}">
    <local:MyContainer.Template>
        <ControlTemplate TargetType="{x:Type local:MyContainer}">
            <Grid>
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter/>
                </Border>
                <ResizeGrip x:Name="PART_Resizer" HorizontalAlignment="Right" VerticalAlignment="Bottom"
                            Width="20" Height="20"/>
            </Grid>
        </ControlTemplate>
    </local:MyContainer.Template>
</local:MyContainer>

您现在可以把这个模板的任何地方,因为它没有任何声明事件处理程序,所以是独立的代码隐藏文件。您现在都封装在一个特定的UI类的UI逻辑的,但你能在你的虚拟机通过结合它仍然需要访问数据。

如果你想想看,这是你的方式通常与内置控件进行交互。如果您使用的扩展,你不想切换按钮的点击进入你的虚拟机,并尽量使控制从那里展开,但你可能想知道的扩展是开放的还是封闭的,所以有一个IsExpanded属性,您可以结合和保存和负载数据。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top