1、设置源控件和目标控件的AllowDrop=true
listBox1.AllowDrop = true;
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Name="grid">
<Image Source="{Binding}"/>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="ListBoxItem.PreviewMouseMove" Handler="lbi_PreviewMouseMove"/>
<EventSetter Event="ListBoxItem.QueryContinueDrag" Handler="lbi_QueryContinueDrag"/>
<EventSetter Event="ListBoxItem.GiveFeedback" Handler="lbi_GiveFeedback"/>
</Style>
2、源控件的PreviewMouseMove事件来控制拖动的数据以及效果
AdornerLayer mAdornerLayer = null;
void lbi_PreviewMouseMove(object sender, MouseEventArgs e)
{
ListBoxItem li = sender as ListBoxItem;
if (li != null && li.IsSelected)
{
DragDropAdorner adorner = new DragDropAdorner(li);(DragDropAdorner实现Adorner抽象类)
mAdornerLayer = AdornerLayer.GetAdornerLayer(grid);
mAdornerLayer.Add(adorner);
DataObject dob = new DataObject(li);
DragDrop.DoDragDrop(li, dob, DragDropEffects.Copy);//启动拖拽
mAdornerLayer.Remove(adorner);
}
}
public class DragDropAdorner : Adorner
{
public DragDropAdorner(UIElement parent)
: base(parent)
{
IsHitTestVisible = false; // Seems Adorner is hit test visible?
mDraggedElement = parent as FrameworkElement;
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
if (mDraggedElement != null)
{
Win32.POINT screenPos = new Win32.POINT();
if (Win32.GetCursorPos(ref screenPos))
{
Point pos = PointFromScreen(new Point(screenPos.X, screenPos.Y));
Rect rect = new Rect(pos.X, pos.Y, mDraggedElement.ActualWidth, mDraggedElement.ActualHeight);
drawingContext.PushOpacity(1.0);
Brush highlight = mDraggedElement.TryFindResource(SystemColors.HighlightBrushKey) as Brush;
if (highlight != null)
drawingContext.DrawRectangle(highlight, new Pen(Brushes.Transparent, 0), rect);
drawingContext.DrawRectangle(new VisualBrush(mDraggedElement),
new Pen(Brushes.Transparent, 0), rect);
drawingContext.Pop();
}
}
}
FrameworkElement mDraggedElement = null;
}
public static class Win32
{
public struct POINT { public Int32 X; public Int32 Y; }
// During drag-and-drop operations, the position of the mouse cannot be
// reliably determined through GetPosition. This is because control of
// the mouse (possibly including capture) is held by the originating
// element of the drag until the drop is completed, with much of the
// behavior controlled by underlying Win32 calls. As a workaround, you
// might need to use Win32 externals such as GetCursorPos.
[DllImport("user32.dll")]
public static extern bool GetCursorPos(ref POINT point);
}
3、目标控件接收数据,使用DragDrop.Drop事件(以Button为例DragDrop.Drop="button1_Drop")
private void button1_Drop(object sender, DragEventArgs e)
{
Point p = e.GetPosition(button1);
HitTestResult result = VisualTreeHelper.HitTest(button1, p);
if (result == null)
return ;
ListBoxItem li=e.Data.GetData(typeof(ListBoxItem)) as ListBoxItem;
}
注:参见http://www.cnblogs.com/loveis715/archive/2011/12/05/2277384.html
本文链接
一般来说,在T-SQL时代,随机排序可以进行newid()产生出guid值来实现,代码一般为:
而到了linq to sql时代,由于产生的语句为延时的(可能是这个原因),所以你用类似这代码:
是不能实现的,这时,如果你的linq to sql非要找个实现的方法,可以在当前数据上下文类中,加个函数:(注意,我们为了扩展性,最要新建一个分
部来做这事)
2 /// 数据上下文扩展
3 /// </summary>
4 public partial class dbDataContext
5 {
6 /// <summary>
7 /// 随机排序
8 /// </summary>
9 /// <returns></returns>
10 [Function(Name = "NewID", IsComposable = true)]
11 public Guid NewID()
12 {
13 return ((Guid)(this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())))
.ReturnValue));
14
15 }
16 }
具体扩展代码:
如果希望按着某个字符串中字符出现的次序,进行特定的排序,可以使用IndexOf,代码如下:
2 linq.ToList().OrderByDescending(a => productids
3 .IndexOf(a.MC_ProductID))
4 .ToList();
有时,我们要为多个字段进行主要,次要的排序,这时,可以用linq自带的ThenBy,比较简单,就不举例子了。
本文链接
对于面向数据的Web应用来说,MVVM模式是一项不错的选择,它借助JS框架提供的“绑定”机制是我们无需过多关注UI(HTML)的细节,只需要操作绑定的数据源。MVVM最早被微软应用于WPF/SL的开发,所以针对Web的MVVP框架来说,Knockout.js(以下简称KO)无疑是“根正苗红”。在进行基于KO的Web应用开发时,我们一般会为具体的Web页面定义针对性的ViewModel,但是在很多情况下很多页面具有相同的UI结构和操作行为,考虑到重用和封装,我们是否为它们创建一个共享的ViewModel呢。最近在一个小项目中,我们对这种方式进行了尝试,觉得是可行的,但同时也发现的一些问题。这篇文章通过一个简化的实例来讨论这种开发方式。[源代码从这里下载]
目录
一、MVVM模式
二、类似的UI结构和操作行为
三、共享的ViewModel
四、Controller的定义
五、View的定义
六、_Layout.cshtml定义
一、MVVM模式
MVVM可以看成是MVC模式的一个变体,Controller被ViewModel取代,但两者具有不同的职能,三元素之间的交互也相同。以通过KO实现的MVVM为例,其核心是“绑定”,我个人又将其分为两类,即“数据的绑定”和“行为的绑定”。所谓数据的绑定,就是将ViewModel定义的数据绑定到View中的UI元素(HTML元素)上,双向/单向绑定同时被支持,而我们通常使用的是双向绑定。而行为绑定体现为事件注册,即View中UI元素的事件(比如某个<button>的click事件)与ViewModel定义的方法(function)进行绑定。
如右图所示,用户行为(比如某个用户点击了页面上的某个Button)触发View的某个事件,与之绑定的定义在ViewModel中的EventHandler(ViewModel的某个方法成员)被自动执行。它可以执行Model,并修改自身维护的数据,由于View和ViewModel的数据绑定是双向的,用户在界面上输入的数据可以被ViewModel捕获,而ViewModel对数据的更新可以自动反映在View上。这样的好出显而易见——我们在通过JS定义UI处理逻辑的时候,无需关注View的细节(View上的HTML),只需要对自身的数据进行操作即可。
二、类似的UI结构和操作行为
通过上面针对MVVM的介绍我们知道ViewModel是三者核心,ViewModel不但定义了绑定在View上的数据,同时也定义了响应View事件的操作。在实际Web应用开发中(尤其是我从事的企业应用开发),往往存在着很多类似的页面。它们不但具有相同的UI结构,对应的操作行为也大同小异,这意味着ViewModel的数据成员和方法成员(实际上KO中用于双向绑定的数据也是方法)也基本上类似,那么出用重用的目的,我们可以考虑为这些相似的页面定义相应的ViewModel。
企业应用很多情况下是在进行数据的维护,即对数据进行基本的CRUD操作。举个实际的例子,假设一个Web应用都采用左图所示的页面和操作行为进行针对不同数据的维护:用户输入查询条件点击“Search”按钮筛选需要操作的数据,获取的数据以表格的形式显示出来;考虑到数据量可能比较大,分页获取往往是必须的;表格的Titile为可点击的链接,用于根据当前列进行排序。
用户可以点击数据行右侧的链接(Update和Delete)修改或者删除当前记录,也可以点击上边的Add按钮天价一条新的数据。数据添加和修改的数据均通过弹出的对话框(如右图所示)的形式进行编辑。
三、共享的ViewModel
那么现在我们希望定义一个公用的“类型”来作为这种页面的ViewModel,并且将相应的数据和行为操作定义其中。虽然这个页面结构比较简单,但是包含的功能还是挺多的,不仅仅具有基本的CRUD操作,还具有排序和分野的功能,所以为这样的页面定义一个公共的ViewMode还是要定义不少的成员。如下所示的就是这个ViewModel的定义,由于我为每个成员加上了注册,所以每个成员的作用还是比较清晰的,在这里我就不一一解释了。补充一点的是,演示实例的样式和对话框功能是通过Bootstrap实现的。