Jason's blog
We have so many needs in our life, but at the end of the day, all we need is...to be needed.
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>
  •     打开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"); });
现在已经差不多了,我们编译下该应用程序。
使用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;
    }
}
从这段代码中,可以看到:
1、你可以通过DragEventArgs.Data.GetData方法使用拖进目标的文件引用
2、由于Silverlight是一个安全的沙箱,所以如果你访问文件的全名(含路径)时,会抛出一个安全的异常。但是你可以访问文件的内容。
3、示例中,我们只获取了第一个文件的内容,但事实上我们很容易获得所有拖入的文件。
 
 




posted on 2011-05-03 17:38  Jason .Z  阅读(1015)  评论(4)    收藏  举报