2016-12-15 63 views
0

PowershellのWPFリストボックスコントロールにドラッグ&ドロップ操作を限定して、テキストファイルのみをドロップできるようにします。 System.Windows.DragDropEffectsプロパティを使用してDragEnterイベントのドロップアクションを防止し、マウスカーソルが拒否されたドロップアクションのユーザーフィードバックを提供するように変更したいと思います。 Dropイベントのファイル拡張子を検証することによって、ドロップされたファイルに対して実行されるアクションを制限できます。しかし、私はよりスムーズなユーザーのやり取りのためにドロップアクションをすべて一緒に防ぐことを好むでしょう。Powershellスクリプトの問題の処理WPFのリストボックスのドラッグ&ドロップの効果

デバッグでは、DragDropEffectプロパティが正しく設定されていることを確認しましたが、イベントハンドラは変更を反映していないようです。 DragEventArgsクラスを使用してPowershellパイプラインを通じてイベントを監視しようとすると、制限があると思います。

WPFリストボックスのDragEnterイベントのコードは次のとおりです。私は、$ _パイプラインで渡されたオブジェクトがSystem.Windows.DragEventArgsクラスのものであることに気付きました。

$listbox.Add_DragEnter({ 
if ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop)) { 
    foreach ($filename in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)) { 
     if(([System.IO.Path]::GetExtension($filename).ToUpper() -eq ".TXT")) { 
      $_.Effects = [System.Windows.DragDropEffects]::All 
      Write-Host 'Dropfile is a .TXT' 
     } 
     else { 
      $_.Effects = [System.Windows.DragDropEffects]::None 
      Write-Host 'Dropfile is NOT a .TXT' 
     } 
    } 
} 
}) 

WinFormsリストボックスを使用してDragDropEffectプロパティを設定すると、正常に動作します。マウスが変更され、ドロップイベントが防止されます。ただし、$ _パイプラインで渡されるオブジェクトは、System.Windows.Forms.DragEventArgsクラスのオブジェクトです。 WPFについては、以下の

Add-Type -AssemblyName System.Windows.Forms 
Add-Type -AssemblyName System.Drawing 
$form = New-Object Windows.Forms.Form 
$listbox = New-Object Windows.Forms.ListBox 
$listbox.AllowDrop = $true 
$listbox.Add_DragEnter({ 
$_.Effect = [Windows.Forms.DragDropEffects]::None 
}) 

$form.Controls.Add($listbox) 
$form.ShowDialog() 

完全なテストコード:

[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 

[xml]$xaml = @' 
<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Remote Execution Toolkit" Height="300" Width="300"> 
<Grid> 
    <ListBox x:Name="listBox" AllowDrop="True" Height="250" HorizontalAlignment="Center" Width="250"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <CheckBox IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"> 
        <TextBlock Text="{Binding}" TextAlignment="Left" Width="Auto" /> 
       </CheckBox> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 
</Window> 
'@ 

# Load XAML Reader 
$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
$Window=[Windows.Markup.XamlReader]::Load($reader) 

# Map XAML Controls 
$xaml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | ForEach { 
New-Variable -Name $_.Name -Value $Window.FindName($_.Name) -Force 
} 

# Drag Event to validate file extensions for drop effect 
$listbox.Add_DragEnter({ 
if ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop)) { 
    foreach ($filename in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)) { 
     if(([System.IO.Path]::GetExtension($filename).ToUpper() -eq ".TXT")) { 
      $_.Effects = [System.Windows.DragDropEffects]::All 
      Write-Host 'Dropfile is a .TXT' 
     } 
     else { 
      $_.Effects = [System.Windows.DragDropEffects]::None 
      Write-Host 'Dropfile is NOT a .TXT' 
     } 
    } 
} 
}) 

$Window.ShowDialog() 

任意の考えや提案は大歓迎です!

答えて

0

Snoop WPFを実行してイベントや試行錯誤を監視していたGoogle-Fooが大量になった後、間違ったDrag Eventに登録していたことに気付きました。カーソルが許可されていない操作を連続して表示した結果を得るには、DragOverイベントを使用する必要があります。明らか

$listbox.Add_DragOver({ 
    ... 
    $_.Effects = [System.Windows.DragDropEffects]::None 
    ... 
}) 

、マウスが許可されていない操作の表示を維持する制御カーソル上にあるときにDragOverイベントが連続的に発生させ、一方、DragEnterイベントは一度だけ、カーソルが戻って変更することを可能にする火災PowerShellでWPFコードを使用する場合。

これは、別の同僚の開発者を節約して時間を節約できることを願っています。

関連する問題