Silverlight 4: Drag&drop with EventToCommand翻译
这里翻译一个关于拖拽的EventToCommand的实例。
- 首先,我们创建一个可拖拽的Silverlight4应用程序,如图

可以使用VS2010或者blend4来创建
我们需要为应用程序中的文件定义为拖动目标,你可以将任何UI元素设置为可拖动,比如主Grid(这样可以让整个应用程序拖拽的目标)或其他的。为了简便,在我们的例子中,我们使用主Grid作为拖拽目标。
- 设置AllowDrop 属性为True,如图

代码如下:
<Grid x:Name="LayoutRoot"
AllowDrop="True"
Background="#FF9F9F9F">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding DroppedFileContent}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap"
TextTrimming="WordEllipsis" />
</Grid>
AllowDrop="True"
Background="#FF9F9F9F">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding DroppedFileContent}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap"
TextTrimming="WordEllipsis" />
</Grid>
- 打开MainViewModel,添加一个绑定属性。
- 提示,如果你安装了MVVM light toolkit(包括代码片段),你可以使用以下快捷键:
- 键入mvvminpc,敲tab键展开代码片段,输入属性名称,再按tab键,设置属性类型,再按tab键设置属性值,代码如下:
/// <summary>
/// The <see cref="DroppedFileContent" /> property's name.
/// </summary>
public const string DroppedFileContentPropertyName = "DroppedFileContent";
private string _droppedFile = "Drop file here";
/// <summary>
/// Gets the DroppedFileContent property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string DroppedFileContent
{
get
{
return _droppedFile;
}
set
{
if (_droppedFile == value)
{
return;
}
_droppedFile = value;
RaisePropertyChanged(DroppedFileContentPropertyName);
}
}
- 之后我们在MainViewModel中添加RelayCommand<DragEventArgs>属性。将其命名为HandleDrapCommand。此时需要Galasoft.MvvmLight.Command和System以及System.Windows的命名空间引用。代码如下:
public RelayCommand<DragEventArgs> HandleDropCommand { get;private set; }
- 最后,在MainViewModel的构造函数中,初始化该事件。我们使用它做一个简单的弹出框。代码如下:
HandleDropCommand = new RelayCommand<DragEventArgs>(e => { System.Windows.MessageBox.Show("Drop"); });
- 在main grid中添加一个EventToCommand 触发。该元素是Galasoft.MvvmLight.Extras Dll中的,我们使用我们的模板会自动添加该引用。否则,请手工添加GalaSoft.MvvmLight.dll, GalaSoft.MvvmLight.Extras.dll and System.Windows.Interactivity.dll 这些引用
现在已经差不多了,我们编译下该应用程序。
使用blend打开,在Assets标签中,从Behaviors分类中选择EventToCommand,并拖拽到Grid中
设置,如图

事件的EventName属性为“Drop”
绑定命令属性,如图

注意:如果并没有使用MVVM模板创建,需要手工添加相关代码:
1、在MainPage.xaml中,添加命名空间:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
2、手工添加事件触发代码
<i:Interaction.Triggers><i:EventTrigger EventName="Drop" SourceName="LayoutRoot" ><GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding HandleDropCommand, Mode=OneWay}"/></i:EventTrigger></i:Interaction.Triggers>
此时就可以做测试了,我们可以看到将文件拖入控件位置是,鼠标的样式已经发生了变化(其实这只是设置AllowDrop="True"
后的效果)
后的效果)

放开鼠标,你可以看到已经执行了我们刚才编写的弹出窗口。
下面我们改写弹出窗口的代码为:
if (e.Data == null)
{
return;
}
var files = e.Data.GetData(DataFormats.FileDrop)
as FileInfo[];
// This works with multiple files, but in that
// simple case, let's just handle the 1st one
if (files == null
|| files.Length == 0)
{
DroppedFileContent = "No files";
return;
}
var file = files[0];
if (!file.Extension.ToLower().Equals(".txt"))
{
DroppedFileContent = "Not a TXT file";
return;
}
using (var stream = file.OpenRead())
{
using (var reader = new StreamReader(stream))
{
// Read the first line
var line = reader.ReadLine();
DroppedFileContent = line;
}
}
{
return;
}
var files = e.Data.GetData(DataFormats.FileDrop)
as FileInfo[];
// This works with multiple files, but in that
// simple case, let's just handle the 1st one
if (files == null
|| files.Length == 0)
{
DroppedFileContent = "No files";
return;
}
var file = files[0];
if (!file.Extension.ToLower().Equals(".txt"))
{
DroppedFileContent = "Not a TXT file";
return;
}
using (var stream = file.OpenRead())
{
using (var reader = new StreamReader(stream))
{
// Read the first line
var line = reader.ReadLine();
DroppedFileContent = line;
}
}
从这段代码中,可以看到:
1、你可以通过DragEventArgs.Data.GetData方法使用拖进目标的文件引用
2、由于Silverlight是一个安全的沙箱,所以如果你访问文件的全名(含路径)时,会抛出一个安全的异常。但是你可以访问文件的内容。
3、示例中,我们只获取了第一个文件的内容,但事实上我们很容易获得所有拖入的文件。
浙公网安备 33010602011771号