从工具箱到画板,让我想起来从百草园到三味书屋,虽然驴嘴不对马口,但是没有下文了。

控件从工具箱到画板的拖动让我想到了tookit中DragDropTarget控件,工具箱好说用ListBox或者TreeView,画板就不知道怎么搞了,于是决定自己做DragDrop。

先贴张图片:

左侧的是一个listbox,右侧红色的是Canvas。创建一个类库DragDropLibrary(这个名不知道好不好听)。

点击左侧的ListBox,然后移动鼠标到右侧红色部分,松开鼠标控件就放到松开的位置,思路就这么简单。

ListBox的Xaml:(Controls = new string[3] { "TextBox", "Button", "TextBlock" };这个是给ListBox的数据,测试。。。)

<ListBox x:Name="ToolBox" ItemsSource="{Binding Controls,Mode=OneTime}">
    <ListBox.ItemTemplate>
        <DataTemplate >
            <TextBlock Text="{Binding}" MouseLeftButtonDown="OnListBoxItemMouseLeftButtonDown" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Item就一个TextBlock,我们要注册MouseLeftButtonDown事件。

在DragDropLibrary中添加一个类:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;namespace DragDropLibrary
{public static class DragDropManage{private static Panel _root, _board;//Droppublic delegate void Drop(DragDropEventArgs target);private static Drop _OnDrag;private static DragDropEventArgs eveArgs;//鼠标拖动时跟随效果private static Image _MouseEffert;/// <summary>/// 拖动之前调用/// </summary>/// <param name="root">根Panel(Children中包含工具箱和画板)</param>/// <param name="board">画板</param>public static void Register(Panel root, Panel board){_root = root;_board = board;if (_root is Grid){Grid.SetColumnSpan(_MouseEffert, (_root as Grid).ColumnDefinitions.Count+1);Grid.SetRowSpan(_MouseEffert, (_root as Grid).RowDefinitions.Count+1);}}static DragDropManage(){_MouseEffert = new Image();}public static void BeginDrag(object sender, MouseButtonEventArgs e, Drop drop){FrameworkElement target = sender as FrameworkElement;WriteableBitmap bitmap = new WriteableBitmap(target, new TranslateTransform());_MouseEffert.Source =bitmap;_MouseEffert.Height = bitmap.PixelHeight;_MouseEffert.Width = bitmap.PixelWidth;_root.Children.Add(_MouseEffert);Point position = e.GetPosition(_root);_MouseEffert.Margin = new Thickness(position.X, position.Y, 0, 0);_MouseEffert.HorizontalAlignment = HorizontalAlignment.Left;_MouseEffert.VerticalAlignment = VerticalAlignment.Top;_MouseEffert.CaptureMouse();eveArgs = new DragDropEventArgs(target);_OnDrag = drop;_root.MouseMove += OnRootMouseMove;_root.MouseLeftButtonUp += OnRootMouseLeftButtonUp;}private static void Clear(){_root.MouseMove -= OnRootMouseMove;_root.MouseLeftButtonUp -= OnRootMouseLeftButtonUp;_root.Children.Remove(_MouseEffert);_OnDrag = null;eveArgs = null;}private static void OnRootMouseLeftButtonUp(object sender, MouseButtonEventArgs e){eveArgs.Position = e.GetPosition(_board);_OnDrag(eveArgs);Clear();}private static void OnRootMouseMove(object sender, MouseEventArgs e){Point position = e.GetPosition(_root);_MouseEffert.Margin = new Thickness(position.X, position.Y, 0, 0);Point currentPosition = e.GetPosition(_board);if (currentPosition.X > 0 && currentPosition.X < _board.ActualWidth&& currentPosition.Y > 0 && currentPosition.Y < _board.ActualHeight){eveArgs.Accept = true;}else{eveArgs.Accept = false;}}}
}
using System;
using System.Windows;namespace DragDropLibrary
{public class DragDropEventArgs : EventArgs{public bool Accept { get; set; }public Point Position { get; internal set; }public FrameworkElement Target { get; private set; }public DragDropEventArgs(FrameworkElement target){Target = target;Position = new Point(0, 0);}}
}

这个EventArgs类也一并贴出。

DragDropManage我做成了静态类,我的电脑只有一个鼠标,而且我也没有多点触控的装备,不知道多点触控能不能同时托两个或者更多控件。

在最最最开始,我们需要初始化DragDropLibrary.DragDropManage.Register(LayoutRoot, BoardCanvas);

LayoutRoot这个都知道,就是程序的根容器,BoardCanvas就是上面说的红色的Canvas。

TextBlock鼠标点击事件,这时我们就开始拖动了。Drop1是一个方法,用来当我们松开鼠标时的回调方法。

private void OnListBoxItemMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
            DragDropLibrary.DragDropManage.BeginDrag(sender, e, Drop1);
}

public void Drag1(DragDropLibrary.DragDropEventArgs target)
{if (target.Accept){string name = (target.Target as TextBlock).Text;FrameworkElement element = null;Type type = GetTypeFromString(name);if (type != null){element = Activator.CreateInstance(type) as FrameworkElement;if (target.Position != null){Canvas.SetLeft(element, target.Position.X);Canvas.SetTop(element, target.Position.Y);}element.Width = 80;element.Height = 40;BoardCanvas.Children.Add(element);}}
}
private Type GetTypeFromString(string typeName)
{Type type = null;typeName = "System.Windows.Controls." + typeName;Assembly assembly = Assembly.Load("System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e");type = assembly.GetType(typeName);return type;
}

在Drop1中Target是ListBox中的TextBlock所以直接转了。

几点说明:

1.DragDropEventArgs中Accept是用来说明,松开鼠标时,当前鼠标的位置是不是落在Canvas中。Position指示当前位置

2.DragDropEventArgs中Target是鼠标点击时的控件。

3.生成控件我是根据名称和程序集,这两个东西获取的,一开始我设想的就是把所有的控件存到Xml文件中,包括他的中文名,全名,以及程序集,这样ListBox中的控件就可以反射出来了。

4.拖动时要在根容器中注册MouseMove事件以及MouseDown。

5.打了个漫长的电话就不知道该说些什么了,今天周五,各位大侠玩的开心。

本人菜鸟一个,刚刚从学校步入社会,还有很多地方需要向大家学习。开博也是为了和大家更好的交流,将自己的小小的代码拿来让大家批评指正。。。。

转载于:https://www.cnblogs.com/flyking/archive/2011/01/21/1941696.html

Silverlight智能表单(2)从工具箱到画板相关推荐

  1. Silverlight智能表单(3)之XML存储

    智能表单的存储要么存到数据库中,要么存到Xml文件中,以我目前的知识水平就这么两种想法了. 我最初的想法是存储到xml文件中,OK,说一下我的大体构架,该构架挺失败的(至少我是这样认为),但是我也没有 ...

  2. Python项目-Day32-HTML5-语义化标签-智能表单-选择器

    Python项目-Day32-HTML5-语义化标签-智能表单-选择器 HTML5是什么? HTML5是一个新的网络标准,目标是取代现有的HTML 4.01和XHTML 1.0 标准.它希望能够减少互 ...

  3. html5下拉智能,HTML5新增标签 + 智能表单

    一.HTML5的新增语义标签 1. 全新语义化标签 :用来定义文档或应用程序中的区域或章节. :用来定义文档的主导航区域,其中的链接指向其他页面或当前页面的某些区域. 用来包裹独立的内容片段,通常用来 ...

  4. BootStrap 智能表单系列 五 表单依赖插件处理

    这一章比较简单哦,主要就是生产表单元素后的一些后续处理操作,比如日期插件的渲染.一些autocomplete的处理等,在回调里面处理就可以了, demo: $("input.date-pic ...

  5. html 表单自动数值,web前端学习技术之对HTML5 智能表单的理解

    原标题:web前端学习技术之对HTML5 智能表单的理解 Html5新增input的form属性,用于指向特定form表单的id,实现input无需放在form标签之中,即可通过表单进行提交. - t ...

  6. 智能表单一键分发,快速收集信息

    功能概述 智能表单是爱用旗下的表单系统,满足企业各种表单场景的使用,支持分享到微信.公众号.小程序.微博.Qzone等多种渠道. 问卷调查:极速创建各类调研问卷,如产品满意度调查.市场调研等. 报名登 ...

  7. ABAP调试和智能表单

    DEBUG基本  F5键:以循序渐进的方式执行程序行.  F6键:逐块执行程序(例如:方法.功能模块和子程序),而不进入单个代码块.  F7键:一起执行块中的所有代码行(例如:方法.函数模块和子 ...

  8. 使用JavaScript创建智能表单

    使用javascript创建智能表单 2000-05-26· 吕晓波·CPCW 验证用户输入 在我们的网站中,经常会加入一些表单,要求用户输入类似姓名或邮件地址等的个人信息.为了确保用户输入的信息符合 ...

  9. Web小案例——智能表单

    一.完成效果  二.代码 <!DOCTYPE html> <html><head><meta charset="utf-8">< ...

  10. HTNL5智能表单(新的表单类型、属性、虚拟键盘适配)

    3. 智能表单 3.1. 新的表单类型 email - 限定输入内容为邮箱地址,表单提交时会校验格式 url - 限定输入内容为URL,表单提交时会校验格式 number - 限定输入内容为数字,表单 ...

最新文章

  1. 薛宇 AI boom
  2. c# webservice生成客户端及使用时碰到decimal类型时的特殊处理
  3. Github+Hexo搭建静态博客
  4. 用户注册 - 判断用户名存在
  5. 通过C#+AJAX实现倒计时
  6. 比特币近24小时内链上交易额有所上升,约为345.44亿美元
  7. SVN的使用及MyEclipse的集成
  8. 换一种方式去思考--microsoft for win server03
  9. [渝粤教育] 宁波财经学院 创业机会识别 参考 资料
  10. 飘云阁15周年逆向破解教程
  11. 本地html导入印象笔记,LocalNote,让你像使用本地文件一样使用印象笔记(支持 markdown 格式)...
  12. 一文深度揭秘3GPP:2G/3G/4G/Pre-5G标准化制定流程是这样的
  13. 关于STM32PWM占空比的总结
  14. 谷歌VR展示360度全景图
  15. 为什么c语言输出到文件慢,【图片】今天写几个性能测试,为什么C语言跑得这么慢呢??【c语言吧】_百度贴吧...
  16. 华师在线计算机网络,华师在线-作业计算机网络.docx
  17. C语言 阿拉伯数字转换为汉语大写数字金额程序分析及源码
  18. mysql使得df和du不一致_df和du显示的磁盘空间使用情况不一致的原因及处理
  19. keil c支持汇编语言吗,keil中用汇编实现hello.c的功能
  20. 高可用架构之高可用的应用和服务

热门文章

  1. 前端过滤特殊字符、表情包
  2. JavaSE基础笔记——File概述、方法递归、字符集、IO流
  3. 安卓中如何获取MD5码
  4. 锁定计算机后怎么解锁,电脑锁住了怎么解锁
  5. 造成笔记本电池损耗的主要原因
  6. 为promise增加abort功能
  7. js 根据公历日期 算出农历_JS获取农历日期具体实例
  8. 2G、 3G、 4G、5G的区别
  9. python selenium span_如何使用selenium从span获取文本
  10. KMplayer字幕