Silverlight 4:为什么物品不可移动?

时间:2010-08-24 02:32:45

标签: silverlight silverlight-4.0 drag-and-drop draggable

有一个“字段”,某些项目可以拖动:

这是一个XAML代码:

                <Canvas Height="180" Width="169" >
                    <Image Canvas.Left="0" Canvas.Top="0" Height="180" Width="149"
                           Source="../Picts/field.png"  />

                    <Pages:FieldItem x:Name="Item2" Canvas.Left="129" Canvas.Top="34"
                                MouseLeftButtonDown="Item1_OnMouseLeftButtonDown"
                                MouseLeftButtonUp="Item1_MouseLeftButtonUp"
                                MouseMove="Item1_MouseMove"
                                />
                </Canvas>

代码隐藏:

    private bool bIsCaptured = false;
    double mouseVerticalPosition;
    double mouseHorizontalPosition;

    private void Item1_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        ((FrameworkElement)sender).CaptureMouse();
        bIsCaptured = true;
        mouseVerticalPosition = e.GetPosition(null).Y;
        mouseHorizontalPosition = e.GetPosition(null).X;
    }

    private void Item1_MouseMove(object sender, MouseEventArgs e)
    {
        if (bIsCaptured)
        {
            UserControl item = sender as UserControl;
            if (item != null)
            {
                // Calculate the current position of the object.
                double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
                double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
                double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
                double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);

                // Set new position of object.
                item.SetValue(Canvas.TopProperty, newTop);
                item.SetValue(Canvas.LeftProperty, newLeft);

                // Update position global variables.
                mouseVerticalPosition = e.GetPosition(null).Y;
                mouseHorizontalPosition = e.GetPosition(null).X;
            }
        }
    }

    private void Item1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        UserControl item = sender as UserControl;
        bIsCaptured = false;
        if (item != null)
        {
            item.ReleaseMouseCapture();
        }
    }

我的任务是显示绑定到对象列表的项目集合。如何做到这一点在主题:Silverlight 4: how to display list of custom controls (not in list order)中描述。

唯一缺乏建议的方法是:项目不再可拖动......

此处如果更新控件“holder”的XAML代码(为了一致性目的而提供):

<Canvas Height="180" Width="169" Background="Beige" HorizontalAlignment="Center" >
             <Image Canvas.Left="0" Canvas.Top="0" Height="180" Width="149"
                   Source="../Picts/field.png"  />
             <Pages:MyItemsControl ItemsSource="{Binding SquadFieldPlayers}">
                <Pages:MyItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                         <Canvas Height="180" Width="169" Background="Transparent"
                                 HorizontalAlignment="Center" />
                    </ItemsPanelTemplate>
                </Pages:MyItemsControl.ItemsPanel>
                <Pages:MyItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Pages:FieldItem 
                             MouseLeftButtonDown="Item1_OnMouseLeftButtonDown" 
                             MouseLeftButtonUp="Item1_MouseLeftButtonUp"
                             MouseMove="Item1_MouseMove"
                             />
                    </DataTemplate>
                 </Pages:MyItemsControl.ItemTemplate>
             </Pages:MyItemsControl >
         </Canvas>

所有鼠标事件处理程序都被调用,但项目实际上不可移动......为什么?

1 个答案:

答案 0 :(得分:1)

仍不确定应该如何运作,但我找到了解决方法。方法'Item1_MouseMove'已更新为执行以下操作:

  1. 查找绑定控件的数据对象;
  2. 设置该对象的'FieldCoordX'和'FieldCoordY'属性,而不是设置控件的'Canvas.LeftProperty'和'Canvas.RightProperty'。
  3. 看起来像这样:

        private void Item1_MouseMove(object sender, MouseEventArgs e)
        {
            if (bIsCaptured)
            {
                FrameworkElement element = sender as FrameworkElement;
                if (element != null)
                {
                    ISquadPlayerViewModel vmPlayer = element.DataContext as ISquadPlayerViewModel;
                    if (vmPlayer != null)
                    {
                        // Calculate the current position of the object.
                        double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
                        double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
                        double newLeft = deltaH + vmPlayer.FieldCoordX;
                        double newTop = deltaV + vmPlayer.FieldCoordY;
    
                        // Set new position of object.
                        vmPlayer.FieldCoordX = newLeft;
                        vmPlayer.FieldCoordY = newTop;
                    }
    
                    // Update position global variables.
                    mouseVerticalPosition = e.GetPosition(null).Y;
                    mouseHorizontalPosition = e.GetPosition(null).X;
                }
            }
        }
    

    要添加到原始描述中的另一项,自定义托管所有控件的'ItemsControl'对象:

    public class MyItemsControl : ItemsControl
    {
        protected override void PrepareContainerForItemOverride(
                                      DependencyObject element, object item)
        {
            FrameworkElement contentitem = element as FrameworkElement;
            if (contentitem != null)
            {
                Binding leftBinding = new Binding("FieldCoordX");
                Binding topBinding = new Binding("FieldCoordY");
                leftBinding.Mode = BindingMode.TwoWay;
                topBinding.Mode = BindingMode.TwoWay;
                contentitem.SetBinding(Canvas.LeftProperty, leftBinding);
                contentitem.SetBinding(Canvas.TopProperty, topBinding);
    
                base.PrepareContainerForItemOverride(element, item);
            }
        }
    }
    

    如您所见,我们的控件已经绑定到数据对象的属性。所以我们需要更新控制数据,而不是对象数据。

    如果有人对更多细节感兴趣,请询问。我会尽力帮忙。