如何在我的“Metro Style”应用程序中的 WPF 中进行拖放?

Posted

技术标签:

【中文标题】如何在我的“Metro Style”应用程序中的 WPF 中进行拖放?【英文标题】:How to do Drag and Drop in WPF in my "Metro Style" app? 【发布时间】:2012-05-31 11:09:47 【问题描述】:

我正在尝试创建一些对 Windows Metro 风格应用程序的原始模仿。到目前为止,我所做的是在ObservableCollection 的窗口中添加新图块,我可以使用ContextMenu 更改它们的颜色并删除它们。现在我想通过实际预览拖动来进行拖放(使用半透明瓷砖)。我尝试自己使用许多描述 WPF 中 DragDrop 类的教程来完成它,但我不得不承认我无法理解它,我需要帮助。我试着关注:this tutorial。这是我的应用程序的screenshot: 还有我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace Metro_Pawel_Michna

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    
        private ObservableCollection<myButton> _tiles = new ObservableCollection<myButton>();
        Random r = new Random();
        private int index = -1;
        private List<Color> myColors = new List<Color>();
        public MainWindow()
        
            InitializeComponent();
            this.DataContext = _tiles;
            webBrowser.Visibility = Visibility.Collapsed;
            btnClose.Visibility = Visibility.Collapsed;
            myColors.Add(Colors.DarkCyan);
            myColors.Add(Colors.Black);
            myColors.Add(Colors.DarkGoldenrod);
            myColors.Add(Colors.DarkBlue);
            myColors.Add(Colors.DarkGray);
            myColors.Add(Colors.DarkKhaki);
        

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        
            myButton b = new myButton();
            b.Content = txtUrl.Text;
            b.MouseDoubleClick += new MouseButtonEventHandler(tileDbl_Click);
            b.MouseRightButtonUp += new MouseButtonEventHandler(b_MouseRightButtonUp);

            Color random = new Color();
            int losuj = r.Next(6);
            b.colorIndex = losuj;

            random = myColors.ElementAt(losuj);

            LinearGradientBrush lgb = new LinearGradientBrush(Colors.White, random, 45);
            lgb.StartPoint = new Point(-0.5,-0.5);
            lgb.EndPoint = new Point(1, 1);
            b.Background = lgb;
            _tiles.Add(b);
        

        private void tileDbl_Click(object sender, RoutedEventArgs e)
        
            const string http = "http://";
            const string https = "https://";
            string address = (sender as Button).Content.ToString();

            if (String.Compare(http, 0, address, 0, 6) == 0 && address.Length > 7) webBrowser.Navigate(address);
            else if (String.Compare(https, 0, address, 0, 7) == 0 && address.Length > 8) webBrowser.Navigate(address);
            else webBrowser.Navigate("http://www.google.com/search?q=" + address);

            tilesBox.Visibility = Visibility.Collapsed;
            btnClose.Visibility = Visibility.Visible;
            txtUrl.Visibility = Visibility.Collapsed;
            btnAdd.Visibility = Visibility.Collapsed;
            toolbar.HorizontalAlignment = HorizontalAlignment.Right;
            webBrowser.Visibility = Visibility.Visible;
        

        private void btnClose_Click(object sender, RoutedEventArgs e)
        
            tilesBox.Visibility = Visibility.Visible;
            btnClose.Visibility = Visibility.Collapsed;
            txtUrl.Visibility = Visibility.Visible;
            btnAdd.Visibility = Visibility.Visible;
            toolbar.HorizontalAlignment = HorizontalAlignment.Left;
            webBrowser.Visibility = Visibility.Collapsed;
        

        private void Remove_Click(object sender, RoutedEventArgs e)
        
            _tiles.RemoveAt(index);
        

        private void b_MouseRightButtonUp(object sender, RoutedEventArgs e)
        
            index = _tiles.IndexOf(sender as myButton);
        

        private void ChangeColor_Click(object sender, RoutedEventArgs e)
        
            myButton b = _tiles.ElementAt(index);
            LinearGradientBrush lgb;
            if (b.colorIndex != myColors.Count - 1)
                lgb = new LinearGradientBrush(Colors.White, myColors.ElementAt(++b.colorIndex), 45);
            else
            
                lgb = new LinearGradientBrush(Colors.White, myColors.ElementAt(0), 45);
                b.colorIndex = 0;
            
            lgb.StartPoint = new Point(-0.5, -0.5);
            lgb.EndPoint = new Point(1, 1);
            b.Background = lgb;
        
    

XAML:

<Window x:Class="Metro_Pawel_Michna.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Metro_Pawel_Michna="clr-namespace:Metro_Pawel_Michna"
        Title="MainWindow" Height="350" Width="525" MinWidth="180" MinHeight="200">
    <DockPanel LastChildFill="True">
        <ToolBarTray Name="toolbar" DockPanel.Dock="Top">
            <ToolBar>
                <TextBox Name="txtUrl">Type an URL</TextBox>
                <Button Name="btnAdd" Click="btnAdd_Click">Add</Button>
                <Button Name="btnClose" Click="btnClose_Click">Close</Button>
            </ToolBar>
        </ToolBarTray>
        <WebBrowser Height="auto" Name="webBrowser" Width="auto" />
        <ScrollViewer>
            <ItemsControl Name="tilesBox" ItemsSource="Binding">
                <ItemsControl.ContextMenu>
                    <ContextMenu Name="contextMenu">
                        <MenuItem Header="Remove" Click="Remove_Click"/>
                        <MenuItem Header="Change color" Click="ChangeColor_Click"/>
                    </ContextMenu>
                </ItemsControl.ContextMenu>
                <ItemsControl.Resources>
                    <Style TargetType="x:Type Metro_Pawel_Michna:myButton">
                        <Setter Property="Width" Value="120"/>
                        <Setter Property="Height" Value="120"/>
                        <Setter Property="Margin" Value="10"/>
                        <Setter Property="Foreground" Value="White" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Grid>
                                        <Rectangle Fill="TemplateBinding Background" />
                                        <ContentPresenter Content="Binding Path=Content, RelativeSource=RelativeSource TemplatedParent" VerticalAlignment="Center" HorizontalAlignment="Center" />
                                    </Grid>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ItemsControl.Resources>

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </ScrollViewer>

    </DockPanel>

</Window>

【问题讨论】:

执行 DragDrop.Drag 和 DragDrop.Drop。您可以在项目或中继器控件上实现。我认为您将需要升级到 ListView 但 ScrollViewer 也可能支持它。我发现在项目中实施更直接但也更具限制性。 查看 MSDN Mag 中的 Charles Petzolds 文章。你应该在那里找到你的答案。抱歉,不确定是哪一个,但可以搜索 2010、2011 年的问题。 JGD 【参考方案1】:

您可以尝试使用一些拖放框架来实现此功能,例如 gon-wpf-dragdrop -

GongSolutions.Wpf.DragDrop 库是一个拖放框架,用于 WPF。它具有以下特点:

与 MVVM 一起使用:拖放的逻辑可以放在 ViewModel 中。无需将代码放在代码隐藏中,而是 附加属性用于绑定到拖放处理程序 一个视图模型。 适用于多项选择。 可以在同一控件内或在控件之间拖动数据重新排序

http://code.google.com/p/gong-wpf-dragdrop/

重新排序是您正在寻找的...

如果您不想使用任何框架,那么我建议您阅读这些文章 -

How can I drag and drop items between data bound ItemsControls? || WayBack Link

http://www.codeproject.com/Articles/37161/WPF-Drag-and-Drop-Smorgasbord

并浏览一些实现拖放的控件的源代码 -

Drag and Drop Controls

【讨论】:

"如何在数据绑定的 ItemsControls 之间拖放项目?"此链接已损坏 @FosterZ 感谢您指出这一点,我添加了一个 Wayback 链接来访问该页面的缓存版本。

以上是关于如何在我的“Metro Style”应用程序中的 WPF 中进行拖放?的主要内容,如果未能解决你的问题,请参考以下文章

令人印象深刻的组件库,用于富有表现力的web开发!使用Metro Style中的第一个前端组件库在web上构建响应项目。现在每天都有更多的机会!

WPF 自定义Metro Style窗体

在 Metro Style 应用程序中保存本地数据

Metro Style App MFT“类未注册”错误

Google Places API 和 Windows 8 Metro Style 应用程序

如何在我的 android 应用程序中的任何位置使实例可用或可访问