I want the user to drag and drop a .txt file into a field. I created a Border for this. I wrote a helpful c# code that checks for drag and drop states. The following application codes understand when the user drags and drops the file.
I can understand that the user brought the file to the field. So how can I tell if the user removed the file from that area?
Xaml Code
<Border BorderThickness="1,1,1,1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.ColumnSpan="5"
Grid.RowSpan="5"
Width="500"
Opacity="0.5"
Background="LightGray"
Height="200"
helper:DropFilesBehaviorExtension.IsEnabled ="True">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding DragDropVisibility}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border.BorderBrush>
<DrawingBrush Viewport="0,0,8,8" ViewportUnits="Absolute" TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0,0,50,50" />
<RectangleGeometry Rect="50,50,50,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.BorderBrush>
<TextBlock Text="Drag and drop the file you want to view onto the screen!"
FontSize="18"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
DropFilesBehavisorExtension
public class DropFilesBehaviorExtension
{
public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached(
"IsEnabled", typeof(bool), typeof(DropFilesBehaviorExtension), new FrameworkPropertyMetadata(default(bool), OnPropChanged)
{
BindsTwoWayByDefault = false,
});
private static void OnPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is FrameworkElement fe))
throw new InvalidOperationException();
if ((bool)e.NewValue)
{
fe.AllowDrop = true;
fe.Drop = OnDrop;
fe.PreviewDragOver = OnPreviewDragOver;
}
else
{
fe.AllowDrop = false;
fe.Drop -= OnDrop;
fe.PreviewDragOver -= OnPreviewDragOver;
}
}
private static void OnPreviewDragOver(object sender, DragEventArgs e)
{
// Border opacity will be raised on drag.
e.Effects = DragDropEffects.Move;
e.Handled = true;
}
private static void OnDrop(object sender, DragEventArgs e)
{
var dataContext = ((FrameworkElement)sender).DataContext;
if (!(dataContext is IFilesDropped filesDropped))
{
if (dataContext != null)
Trace.TraceError($"Binding error, '{dataContext.GetType().Name}' doesn't implement '{nameof(IFilesDropped)}'.");
return;
}
if (!e.Data.GetDataPresent(DataFormats.FileDrop))
return;
if (e.Data.GetData(DataFormats.FileDrop) is string[] files)
filesDropped.OnFilesDropped(files);
}
public static void SetIsEnabled(DependencyObject element, bool value)
{
element.SetValue(IsEnabledProperty, value);
}
public static bool GetIsEnabled(DependencyObject element)
{
return (bool)element.GetValue(IsEnabledProperty);
}
}
public interface IFilesDropped
{
void OnFilesDropped(string[] files);
}
CodePudding user response:
DragLeave function solved my problem. The function is triggered as soon as the mouse drag leaves the desired area.
fe.DragLeave = Fe_DragLeave;
private static void Fe_DragLeave(object sender, DragEventArgs e)
{
}