2012-05-24 5 views
5

Próbuję stworzyć jakąś prymitywną imitację aplikacji Windows Metro. Do tej pory dodałem nowe kafelki do okna w ObservableCollection, mogę zmienić ich kolor i usunąć je za pomocą ContextMenu. Teraz chcę zrobić przeciągnij i upuść z rzeczywistym podglądem przeciągania (z półprzezroczystą płytką). Próbowałem zrobić to sam, korzystając z wielu tutoriali opisujących klasę DragDrop w WPF, ale muszę przyznać, że po prostu nie mogę tego zrozumieć i potrzebuję pomocy. Próbowałem wykonać: this tutorial. Oto screenshot mojej aplikacji: screenshot i mój kod:Jak przeciągnąć i upuścić WPF w mojej aplikacji "Metro Style"?

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> 
+0

Impelment DragDrop.Drag i DragDrop.Drop. Możesz zaimplementować na kontrolerze pozycji lub przemiennika. Myślę, że będziesz musiał podejść do ListView, ale ScrollViewer również może go wspierać. Znalazłem wdrażanie w przedmiotach bardziej bezpośrednich, ale także bardziej restrykcyjnych. – Paparazzi

+0

Sprawdź artykuły Charlesa Petzoldsa w MSDN Mag. Powinieneś znaleźć tam odpowiedź. Przykro nam, ale nie wiem, czy chodzi o problemy z 2010, 2011 roku. JGD –

Odpowiedz

4

Można spróbować użyć jakiegoś Przeciągnij & Opadowej ramy dla realizacji tej funkcji, jak gong-WPF dragdrop -

biblioteka GongSolutions.Wpf.DragDrop to framework drag'n'drop dla WPF. Ma następujące funkcje:

  • Działa z MVVM: logika przeciągania i upuszczania może być umieszczona w ViewModelu. Żaden kod nie musi być umieszczony w codebehind, zamiast tego dołączone właściwości są używane do wiązania do obsługi przeciągania/upuszczania w a ViewModel.
  • Działa z wieloma wyborami.
  • Może przeciągnąć dane w obrębie tej samej kontrolki, aby zmienić kolejność lub między kontrolami.

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

zmiana kolejności jest to, czego szukasz ...

W przypadku, gdy nie chcesz używać żadnych ram następnie chciałbym zasugerować, aby przejść przez tych artykułów -

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

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

i przejść przez kod źródłowy niektórych kontroli wykonawczych przeciągnij & spadek -

Drag and Drop Controls

+0

"Jak przeciągać i upuszczać elementy między elementami ItemsControls związanymi z danymi?" ten link jest zepsuty – FosterZ

+0

@FosterZ Dzięki za wskazanie, dodałem link Wayback, aby uzyskać dostęp do buforowanej wersji tej strony. – akjoshi