代码之家  ›  专栏  ›  技术社区  ›  Budda

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

  •  1
  • Budda  · 技术社区  · 15 年前

    有一个“字段”,其中一些项是可拖动的:

    下面是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 回复  |  直到 8 年前
        1
  •  1
  •   Budda    15 年前

    1. 设置该对象的'FieldCoordX'和'FieldCoordY'属性,而不是设置'Canvas.LeftProperty属性'和'Canvas.RightProperty属性'的控制。

    看起来是这样的:

        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);
            }
        }
    }
    

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