【问题标题】:Custom Drag And Drop UWP自定义拖放 UWP
【发布时间】:2019-06-10 20:08:27
【问题描述】:

我需要创建自定义拖放。我创建了两个列表视图,在第一个列表视图中,通过指针按下事件,我使用自定义图像创建了拖动。唯一缺少的是:成功地将事件拖动或事件指针输入到第二个列表视图的项目的网格中。这不起作用,因为当这种情况发生时,移动的事件仍然处于活动状态。

MainPage.xaml:

<Page
x:Class="Drag_And_Drop_Custom_UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:Drag_And_Drop_Custom_UWP"
mc:Ignorable="d"
Loaded="Page_Loaded"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
    <local:DrugPosition x:Name="CoordinatesDrug"/>
</Page.Resources>
<Grid x:Name="BaseGrid">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListView x:Name="ListViewPerson" ItemsSource="{x:Bind ListPerson}" ItemContainerStyle="{StaticResource ListViewItemRevealStyleDrug}" Margin="50">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Person">
                    <Grid x:Name="GridPerson" Background="Red" PointerPressed="GridPerson_PointerPressed">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{x:Bind Name}" Margin="5"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <ListView x:Name="ListViewHeight" ItemsSource="{x:Bind ListHeight}" ItemContainerStyle="{StaticResource ListViewItemRevealStyleDrug}" Margin="50" Grid.Column="1">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Characteristic">
                    <Grid x:Name="GridHeight" Background="Red" AllowDrop="True" 
                          PointerEntered="GridHeight_PointerEntered"
                          PointerExited="GridHeight_PointerExited"
                          DragEnter="GridHeight_DragEnter"
                          DragLeave="GridHeight_DragLeave">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{x:Bind PersonHeight}" Margin="5"/>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
    <Canvas x:Name="GridForDrop">
        <Grid x:Name="GridLetter" HorizontalAlignment="Left" Height="100" Margin="-128,10,0,0" VerticalAlignment="Top" Width="100" Background="#FF18AA30">
            <TextBlock Text="C" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontSize="72"/>
        </Grid>
        <Image x:Name="ImageToDrugOver" Canvas.Left="{x:Bind CoordinatesDrug.LeftDrugPosition, Mode=OneWay}" Canvas.Top="{x:Bind CoordinatesDrug.TopDrugPosition, Mode=OneWay}"/>
    </Canvas>
</Grid>

MainPage.xaml.cs:

public class Person
{
    public string Name { get; set; }
}
public class Characteristic
{
    public int PersonHeight { get; set; }
}
public class DrugPosition : INotifyPropertyChanged
{
    private double leftDrugPosition;
    public double LeftDrugPosition
    {
        get
        {
            return leftDrugPosition;
        }
        set
        {
            leftDrugPosition = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LeftDrugPosition)));
        }
    }

    private double topDrugPosition;
    public double TopDrugPosition
    {
        get
        {
            return topDrugPosition;
        }
        set
        {
            topDrugPosition = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TopDrugPosition)));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
public sealed partial class MainPage : Page
{
    ObservableCollection<Person> ListPerson = new ObservableCollection<Person>();
    ObservableCollection<Characteristic> ListHeight = new ObservableCollection<Characteristic>();

    public MainPage()
    {
        this.InitializeComponent();
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        ListPerson.Add(new Person() { Name = "Person 1" });
        ListPerson.Add(new Person() { Name = "Person 2" });
        ListPerson.Add(new Person() { Name = "Person 3" });
        ListPerson.Add(new Person() { Name = "Person 4" });
        ListPerson.Add(new Person() { Name = "Person 5" });

        ListHeight.Add(new Characteristic() { PersonHeight = 100 });
        ListHeight.Add(new Characteristic() { PersonHeight = 200 });
        ListHeight.Add(new Characteristic() { PersonHeight = 100 });
        ListHeight.Add(new Characteristic() { PersonHeight = 200 });
        ListHeight.Add(new Characteristic() { PersonHeight = 100 });
    }

    private async void GridPerson_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        Grid GridPersona = sender as Grid;
        Point puntopressd = e.GetCurrentPoint(BaseGrid).Position;
        BitmapImage ImageToDrug = await LoadImageForDrug();
        CoordinatesDrug.LeftDrugPosition = puntopressd.X - 50;
        CoordinatesDrug.TopDrugPosition = puntopressd.Y - 50;
        ImageToDrugOver.Source = ImageToDrug;

        PointerEventHandler moved = null;
        moved = (s, args) =>
        {
            BaseGrid.CapturePointer(e.Pointer);
            Point puntomoved = e.GetCurrentPoint(BaseGrid).Position;
            CoordinatesDrug.LeftDrugPosition = puntomoved.X - 50;
            CoordinatesDrug.TopDrugPosition = puntomoved.Y - 50;

        };

        PointerEventHandler released = null;
        released = (s, args) =>
        {
            Point puntoreleas = e.GetCurrentPoint(BaseGrid).Position;
            ImageToDrugOver.Source = null;
            BaseGrid.PointerMoved -= moved;
            BaseGrid.PointerReleased -= released;
        };
        BaseGrid.PointerMoved += moved;
        BaseGrid.PointerReleased += released;
    }

    private async Task<BitmapImage> LoadImageForDrug()
    {
        RenderTargetBitmap rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(GridLetter);

        InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
        var buffer = await rtb.GetPixelsAsync();

        BitmapImage img = new BitmapImage();
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
        encoder.SetPixelData(
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Straight,
            (uint)rtb.PixelWidth,
            (uint)rtb.PixelHeight,
            DisplayInformation.GetForCurrentView().LogicalDpi,
            DisplayInformation.GetForCurrentView().LogicalDpi,
            buffer.ToArray());
        await encoder.FlushAsync();
        await img.SetSourceAsync(stream);
        return img;
    }

    private void GridHeight_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        Grid GridHeight = sender as Grid;
        GridHeight.Background = new SolidColorBrush(Colors.Yellow);
    }

    private void GridHeight_PointerExited(object sender, PointerRoutedEventArgs e)
    {
        Grid GridHeight = sender as Grid;
        GridHeight.Background = new SolidColorBrush(Colors.Red);
    }

    private void GridHeight_DragEnter(object sender, DragEventArgs e)
    {
        Grid GridHeight = sender as Grid;
        GridHeight.Background = new SolidColorBrush(Colors.Yellow);
    }

    private void GridHeight_DragLeave(object sender, DragEventArgs e)
    {
        Grid GridHeight = sender as Grid;
        GridHeight.Background = new SolidColorBrush(Colors.Red);
    }
}

我怎样才能使拖动事件起作用,或者更确切地说,在这种情况下,即使在移动图像并且第一个列表视图的移动事件处于活动状态时也输入了指针(在第二个列表视图中)?

总是提前感谢!

【问题讨论】:

    标签: c# listview uwp


    【解决方案1】:

    如果要在UWP中实现拖放操作,需要进行以下步骤:

    1. 通过将 CanDrag 属性设置为 true 来启用对元素的拖动。
    2. 构建数据包。系统会自动处理图像和文本,但对于其他内容,您需要处理 DragStarted 和 DragCompleted 事件并使用它们来构建您自己的数据包。
    3. 通过将所有可以接收丢弃内容的元素的 AllowDrop 属性设置为 true 来启用丢弃。
    4. 处理 DragOver 事件,让系统知道元素可以接收哪种类型的拖动操作。
    5. 处理 Drop 事件以接收拖放的内容。

    更多信息,请查看Drag and Drop文档。

    这里是 UWP 官方Drag and drop sample 了解您的详细信息。

    【讨论】:

    • 我知道这一点,但我需要创建这个自定义拖放。
    • @Ticras 该文档解释说,如果您想进行自定义拖放,“您可以使用 Windows.ApplicationModel.DataTransfer.DragDrop.Core 命名空间中的 API 实现您自己的版本”。
    • 有没有可能……举个小例子?因为我不知道从哪里开始......
    • @Ticras 你能告诉我你的详细要求吗?因为我检查了你上面的代码,这只是一般的拖放操作。我没有发现有一些具体的操作。所以,我不明白为什么一般的拖放操作不符合您的要求。
    • 我想自定义listview项上的拖拽图片
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    相关资源
    最近更新 更多