0

如何使用拖放来移动网格中的元素。

即我有一个由 5x3 元素组成的网格,我希望能够从网格中拖动一个元素(通常是一个按钮)并让它在网格中的其他位置放置。

最好有一些突出显示或移动来查看按钮将插入的位置。

目前我只看到代码隐藏中的方法,但肯定有更好的方法,更 MVVM 的方法......

为清楚起见:它是一个 Windows 桌面应用程序

我的网格嵌入在一个列表框中,正如您从我的 XAML 中看到的那样:

<ListBox Margin="0" BorderThickness="0" Padding="0" Grid.Row="1" Background="Lime" SelectionMode="Single" ItemsSource="{Binding Path=CurrentToolTablet.Tools}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
    <ListBox.Template>
        <ControlTemplate TargetType="{x:Type ListBox}">
            <Border x:Name="Bd"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Background="{TemplateBinding Background}"
                    SnapsToDevicePixels="true">
                <ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
                    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </ScrollViewer>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                </Trigger>
                <Trigger Property="IsGrouping" Value="true">
                    <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </ListBox.Template>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Focusable="False" Command="{Binding CmdClickTool}" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
                <Image Source="myimage.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
                </Image>
            </Button>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemContainerStyle>
        <Style>
            <Setter Property="Grid.Column" Value="{Binding Path=Col}"/>
            <Setter Property="Grid.Row" Value="{Binding Path=Row}"/>
            <Setter Property="ContentControl.HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="ContentControl.VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="ContentControl.Margin" Value="0"/>
            <Setter Property="ContentControl.Padding" Value="0"/>
            <Setter Property="Control.BorderThickness" Value="0"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
4

2 回答 2

0

好吧,我不明白你为什么发布 XAML 或者我如何使用它。但这是我的Forms实现,也许你可以使用它。没有动画,但它似乎适用于几种类型的控件。

public partial class ComponentMover : Form
{
    private Control trackedControl;
    private int gridWidth = 100, gridHeight = 20;

    public ComponentMover()
    {
        this.InitializeComponent();
        this.InitializeDynamic();
    }

    void draggable_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (this.trackedControl == null)
            this.trackedControl = (Control)sender;
    }

    void draggable_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (this.trackedControl != null)
        {
            int x = e.X + this.trackedControl.Location.X;
            int y = e.Y + this.trackedControl.Location.Y;
            Point moved = new Point(x - x % this.gridWidth, y - y % this.gridHeight);

            Console.WriteLine(e.X + ", " + e.Y + ", " + ", " + moved.X + ", " + moved.Y);
            if (moved != this.trackedControl.Location)
                this.trackedControl.Location = moved;
        }
    }

    void draggable_MouseUp(object sender, MouseEventArgs e)
    {
        this.trackedControl = null;
    }

    private void AddDragListeners(Control draggable)
    {
        draggable.MouseDown += new MouseEventHandler(draggable_MouseDown);
        draggable.MouseMove += new MouseEventHandler(draggable_MouseMove);
        draggable.MouseUp += new MouseEventHandler(draggable_MouseUp);
    }
}
// Designer code.
partial class ComponentMover
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    private void InitializeDynamic()
    {
        this.AddDragListeners(button1);
        this.AddDragListeners(button4);
        this.AddDragListeners(domainUpDown1);
        this.AddDragListeners(textBox1);
        this.AddDragListeners(checkBox1);
        this.AddDragListeners(radioButton1);

        //this.MouseMove += new System.Windows.Forms.MouseEventHandler(draggable_MouseMove);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.button1 = new System.Windows.Forms.Button();
        this.button4 = new System.Windows.Forms.Button();
        this.domainUpDown1 = new System.Windows.Forms.DomainUpDown();
        this.textBox1 = new System.Windows.Forms.TextBox();
        this.checkBox1 = new System.Windows.Forms.CheckBox();
        this.radioButton1 = new System.Windows.Forms.RadioButton();
        this.SuspendLayout();
        // 
        // button1
        // 
        this.button1.Location = new System.Drawing.Point(13, 13);
        this.button1.Name = "button1";
        this.button1.Size = new System.Drawing.Size(75, 23);
        this.button1.TabIndex = 0;
        this.button1.Text = "button1";
        this.button1.UseVisualStyleBackColor = true;
        // 
        // button4
        // 
        this.button4.Location = new System.Drawing.Point(177, 43);
        this.button4.Name = "button4";
        this.button4.Size = new System.Drawing.Size(75, 23);
        this.button4.TabIndex = 3;
        this.button4.Text = "button4";
        this.button4.UseVisualStyleBackColor = true;
        // 
        // domainUpDown1
        // 
        this.domainUpDown1.Location = new System.Drawing.Point(95, 42);
        this.domainUpDown1.Name = "domainUpDown1";
        this.domainUpDown1.Size = new System.Drawing.Size(74, 20);
        this.domainUpDown1.TabIndex = 4;
        this.domainUpDown1.Text = "domainUpDown1";
        // 
        // textBox1
        // 
        this.textBox1.Location = new System.Drawing.Point(177, 72);
        this.textBox1.Name = "textBox1";
        this.textBox1.Size = new System.Drawing.Size(100, 20);
        this.textBox1.TabIndex = 5;
        // 
        // checkBox1
        // 
        this.checkBox1.AutoSize = true;
        this.checkBox1.Location = new System.Drawing.Point(281, 13);
        this.checkBox1.Name = "checkBox1";
        this.checkBox1.Size = new System.Drawing.Size(80, 17);
        this.checkBox1.TabIndex = 6;
        this.checkBox1.Text = "checkBox1";
        this.checkBox1.UseVisualStyleBackColor = true;
        // 
        // radioButton1
        // 
        this.radioButton1.AutoSize = true;
        this.radioButton1.Location = new System.Drawing.Point(366, 42);
        this.radioButton1.Name = "radioButton1";
        this.radioButton1.Size = new System.Drawing.Size(85, 17);
        this.radioButton1.TabIndex = 7;
        this.radioButton1.TabStop = true;
        this.radioButton1.Text = "radioButton1";
        this.radioButton1.UseVisualStyleBackColor = true;
        // 
        // ComponentMover
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(485, 159);
        this.Controls.Add(this.radioButton1);
        this.Controls.Add(this.checkBox1);
        this.Controls.Add(this.textBox1);
        this.Controls.Add(this.domainUpDown1);
        this.Controls.Add(this.button4);
        this.Controls.Add(this.button1);
        this.Name = "ComponentMover";
        this.Text = "ComponentMover";
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    #endregion

    private System.Windows.Forms.Button button1;
    private System.Windows.Forms.Button button4;
    private System.Windows.Forms.DomainUpDown domainUpDown1;
    private System.Windows.Forms.TextBox textBox1;
    private System.Windows.Forms.CheckBox checkBox1;
    private System.Windows.Forms.RadioButton radioButton1;
}
于 2012-07-06T23:43:51.530 回答
0

我最近制作了一个库,可以拖放按钮并更新它们的大小。我仍在进行一些更新,但您可以使用稳定版本。

https://github.com/noahjames404/DragNDropPager

于 2020-03-19T19:49:19.630 回答