I'm trying to create some primitive imitation of the Windows Metro style application. What I've done so far is adding new tiles to the window in ObservableCollection
, I can change their color and remove them using ContextMenu
. Now I want to do Drag and Drop with actual previewing the dragging (with semi transparent tile). I tried to do it by myself using many tutorials describing the DragDrop class in WPF but I have to admit I just can't understand it and I need help. I tried to follow: this tutorial. Here's a screenshot of my app:
And my code:
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>
You can try to use some Drag & Drop framework to implement this functionality, like gong-wpf-dragdrop -
The GongSolutions.Wpf.DragDrop library is a drag'n'drop framework for WPF. It has the following features:
- Works with MVVM : the logic for the drag and drop can be placed in a ViewModel. No code needs to be placed in codebehind, instead attached properties are used to bind to a drag handler/drop handler in a ViewModel.
- Works with multiple selections.
- Can drag data within the same control to re-order, or between controls.
http://code.google.com/p/gong-wpf-dragdrop/
reordering is what you are looking for...
In case you don't want to use any framework then I would suggest you to go through these articles -
How can I drag and drop items between data bound ItemsControls? || WayBack Link
http://www.codeproject.com/Articles/37161/WPF-Drag-and-Drop-Smorgasbord
and go through source code of some controls implementing drag & drop -
Drag and Drop Controls
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With