none
如何自定义Behavior的处理函数? RRS feed

  • 问题

  •      本人初学WPF和MVVM(prism),现在用到MouseDragElementBehavior来模拟棋子从盒子移动到棋盘的过程,但是MouseDragElementBehavior只是模拟出了棋子(我用的是一个Label)移动的效果,不知道怎么响应MouseUp事件来把棋子放到棋盘中?
    2013年10月19日 1:39

答案

  • 您好,

    根据您的描述,您可以采取以下的方案:
    棋盘使用Canvas绘制,在我的示例中是新建了名为WeiQi的类,实现了MouseUp事件函数:

    public void CvsBoard_MouseUp(object sender, MouseButtonEventArgs e)
    {
                Point p = e.GetPosition(_cvsBoard);
                double gap = _cvsBoard.Width / 20;
                Coordinate cod = Coordinate.GetCoordinateByPoint(p, gap);
                if (!cod.IsValid())
                {
                    return;
                }
                if (_stoneList.FindStone(cod.X, cod.Y) != null)
                {
                    return;
                }
    
                Stone stn = new Stone(++_stoneNumber, cod.X, cod.Y, _cvsBoard);
                if (_stoneList.Add(stn))
                {
                    _stoneRecord.Add(cod);
                    DrawText(stn);
                }
                else
                {
                    _stoneNumber--;
                }
    }

    XAML:

    <Grid Name="gd">
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width="100" />
       <ColumnDefinition />
       <ColumnDefinition Width="100" />
      </Grid.ColumnDefinitions>
           
        <Canvas Name="cvsBoard" Background="#FFFFC000" Grid.Column="1" Width="400" Height="400"
                    HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
            <Grid Background="AliceBlue" Name="gd1" Grid.Column="0">
                <Ellipse Fill="Black" Name="chessblack"  Height="20" Width="20" StrokeThickness="2" Stroke="Black" MouseUp="Ellipse_MouseUp" >
                <i:Interaction.Behaviors>
                    <ei:MouseDragElementBehavior/>
                </i:Interaction.Behaviors>
            </Ellipse>
            </Grid>
            <Grid Background="AliceBlue" Name="gd2" Grid.Column="2">
                <Ellipse Fill="White" Name="chesswhite" IsEnabled="False" Height="20" Width="20" StrokeThickness="2" Stroke="Black" MouseUp="Ellipse_MouseUp">
                    <i:Interaction.Behaviors>
                        <ei:MouseDragElementBehavior/>
                    </i:Interaction.Behaviors>
                </Ellipse>
            </Grid>
        </Grid>

    其中的MouseDragElementBehavior是使用Blend添加,使棋子可以移动。

    当棋子移动到指定位置后,会调用MouseUp事件:

    WeiQi q;
    public MainWindow()
    {
                InitializeComponent();
                q=new WeiQi(this.cvsBoard);
    }
    
    public void Ellipse_MouseUp(object sender, MouseButtonEventArgs e)
    {
                q.CvsBoard_MouseUp(sender,e);
                if (chessblack.IsEnabled == true)
                {
                    chessblack.IsEnabled = false;
                    chesswhite.IsEnabled = true;
                }
                else
                {
                    chessblack.IsEnabled = true;
                    chesswhite.IsEnabled = false;
                }
    }

    使程序开始在棋盘上绘制棋子:

    您可以从SkyDrive上下载我的示例工程:
    http://sdrv.ms/1fPwEOc


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2013年10月21日 10:05
    版主
  • 您好,

    问题一:答案是肯定的,不过如果直接使用Ellipse_MouseUp, 因为DragFinished事件使用的是MouseEventHandler委托,而MouseUp使用的是MouseButtonEventHandler委托,会导致不匹配,需要在Weiqi类中重写匹配的事件函数。

    问题二:好处有几点:
    1) 最少代码支持(不需要CommandBindings)

    2) Command 实现代码易于在 ViewModel 类中改写

    3) 它不依赖于UI元素树工作, 也利于提高性能

    问题三:
    您可以参考这篇文章:http://blog.csdn.net/qing2005/article/details/6601475
    里面有实现方式和示例工程


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 picat 2013年10月22日 9:54
    2013年10月22日 8:19
    版主

全部回复

  • 您好,

    根据您的描述,您可以采取以下的方案:
    棋盘使用Canvas绘制,在我的示例中是新建了名为WeiQi的类,实现了MouseUp事件函数:

    public void CvsBoard_MouseUp(object sender, MouseButtonEventArgs e)
    {
                Point p = e.GetPosition(_cvsBoard);
                double gap = _cvsBoard.Width / 20;
                Coordinate cod = Coordinate.GetCoordinateByPoint(p, gap);
                if (!cod.IsValid())
                {
                    return;
                }
                if (_stoneList.FindStone(cod.X, cod.Y) != null)
                {
                    return;
                }
    
                Stone stn = new Stone(++_stoneNumber, cod.X, cod.Y, _cvsBoard);
                if (_stoneList.Add(stn))
                {
                    _stoneRecord.Add(cod);
                    DrawText(stn);
                }
                else
                {
                    _stoneNumber--;
                }
    }

    XAML:

    <Grid Name="gd">
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width="100" />
       <ColumnDefinition />
       <ColumnDefinition Width="100" />
      </Grid.ColumnDefinitions>
           
        <Canvas Name="cvsBoard" Background="#FFFFC000" Grid.Column="1" Width="400" Height="400"
                    HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
            <Grid Background="AliceBlue" Name="gd1" Grid.Column="0">
                <Ellipse Fill="Black" Name="chessblack"  Height="20" Width="20" StrokeThickness="2" Stroke="Black" MouseUp="Ellipse_MouseUp" >
                <i:Interaction.Behaviors>
                    <ei:MouseDragElementBehavior/>
                </i:Interaction.Behaviors>
            </Ellipse>
            </Grid>
            <Grid Background="AliceBlue" Name="gd2" Grid.Column="2">
                <Ellipse Fill="White" Name="chesswhite" IsEnabled="False" Height="20" Width="20" StrokeThickness="2" Stroke="Black" MouseUp="Ellipse_MouseUp">
                    <i:Interaction.Behaviors>
                        <ei:MouseDragElementBehavior/>
                    </i:Interaction.Behaviors>
                </Ellipse>
            </Grid>
        </Grid>

    其中的MouseDragElementBehavior是使用Blend添加,使棋子可以移动。

    当棋子移动到指定位置后,会调用MouseUp事件:

    WeiQi q;
    public MainWindow()
    {
                InitializeComponent();
                q=new WeiQi(this.cvsBoard);
    }
    
    public void Ellipse_MouseUp(object sender, MouseButtonEventArgs e)
    {
                q.CvsBoard_MouseUp(sender,e);
                if (chessblack.IsEnabled == true)
                {
                    chessblack.IsEnabled = false;
                    chesswhite.IsEnabled = true;
                }
                else
                {
                    chessblack.IsEnabled = true;
                    chesswhite.IsEnabled = false;
                }
    }

    使程序开始在棋盘上绘制棋子:

    您可以从SkyDrive上下载我的示例工程:
    http://sdrv.ms/1fPwEOc


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2013年10月21日 10:05
    版主
  •       感谢回复,例子可行,不过还有两个疑问想请教一下.

          1:MouseDragElementBehavior本身有DragBegun,DragFinished和Dragging三个事件,是不是也可以通过<ei:MouseDragElementBehavior DragFinished="Ellipse_MouseUp"/>的方式来完成?

          2:MVVM是通过DelegateCommand来与控件的Command属性进行绑定的,这样做的好处是什么?就我目前的理解通过指定处理函数(就像上面)以及Addhandler的方式也没有违反MVVM的规范.

          3:如果2中DelagateCommand是推荐做法,那如果我要绑定的控件的默认事件不是我需要的该怎么做?比如我想把一个DelegateCommand绑定到Button的MouseMove事件(Button的Command属性默认响应的是Click事件)或者Label的Click事件(Label甚至没有Command属性)


    • 已编辑 picat 2013年10月22日 4:16
    2013年10月22日 4:15
  • 您好,

    问题一:答案是肯定的,不过如果直接使用Ellipse_MouseUp, 因为DragFinished事件使用的是MouseEventHandler委托,而MouseUp使用的是MouseButtonEventHandler委托,会导致不匹配,需要在Weiqi类中重写匹配的事件函数。

    问题二:好处有几点:
    1) 最少代码支持(不需要CommandBindings)

    2) Command 实现代码易于在 ViewModel 类中改写

    3) 它不依赖于UI元素树工作, 也利于提高性能

    问题三:
    您可以参考这篇文章:http://blog.csdn.net/qing2005/article/details/6601475
    里面有实现方式和示例工程


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 picat 2013年10月22日 9:54
    2013年10月22日 8:19
    版主
  •    非常感谢您的回复,下午我正巧也找到了您提到的这篇参考文章,确实完美的解决了我的问题,再次感谢~!
    2013年10月22日 9:53