Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
{
private int _value;

public MainWindowViewModel()

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Non-nullable field '_myString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Non-nullable field '_pointerTriggersViewModel' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Non-nullable field '_myString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Non-nullable field '_pointerTriggersViewModel' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Non-nullable field '_myString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Non-nullable field '_pointerTriggersViewModel' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Non-nullable field '_myString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Non-nullable field '_pointerTriggersViewModel' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Non-nullable field '_myString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Non-nullable field '_pointerTriggersViewModel' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Non-nullable field '_myString' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.

Check warning on line 15 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Non-nullable field '_pointerTriggersViewModel' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable.
{
PointerTriggersViewModel = new PointerTriggersViewModel();

Expand Down Expand Up @@ -85,9 +85,9 @@

OpenItemCommand = ReactiveCommand.Create<ItemViewModel>(OpenItem);

OpenFilesCommand = ReactiveCommand.Create<IReadOnlyList<IStorageFile>>(OpenFiles);
OpenFilesCommand = ReactiveCommand.Create<IEnumerable<IStorageItem>>(OpenFiles);
SaveFileCommand = ReactiveCommand.Create<Uri>(SaveFile);
OpenFoldersCommand = ReactiveCommand.Create<IReadOnlyList<IStorageFolder>>(OpenFolders);
OpenFoldersCommand = ReactiveCommand.Create<IEnumerable<IStorageFolder>>(OpenFolders);

GetClipboardTextCommand = ReactiveCommand.Create<string?>(GetClipboardText);
}
Expand Down Expand Up @@ -152,13 +152,13 @@
Console.WriteLine($"OpenItemCommand: {item.Value}");
}

private void OpenFiles(IReadOnlyList<IStorageFile> files)
private void OpenFiles(IEnumerable<IStorageItem> files)
{
foreach (var file in files)
{
Console.WriteLine($"OpenFilesCommand: {file.Name}, {file.Path}");

FileItems.Add(file.Path);

Check warning on line 161 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Dereference of a possibly null reference.

Check warning on line 161 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Dereference of a possibly null reference.

Check warning on line 161 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Dereference of a possibly null reference.

Check warning on line 161 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Dereference of a possibly null reference.

Check warning on line 161 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Dereference of a possibly null reference.

Check warning on line 161 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Dereference of a possibly null reference.
}
}

Expand All @@ -166,16 +166,16 @@
{
Console.WriteLine($"SaveFileCommand: {file}");

FileItems.Add(file);

Check warning on line 169 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Dereference of a possibly null reference.

Check warning on line 169 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Dereference of a possibly null reference.

Check warning on line 169 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Dereference of a possibly null reference.

Check warning on line 169 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Dereference of a possibly null reference.

Check warning on line 169 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Dereference of a possibly null reference.

Check warning on line 169 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Dereference of a possibly null reference.
}

private void OpenFolders(IReadOnlyList<IStorageFolder> folders)
private void OpenFolders(IEnumerable<IStorageFolder> folders)
{
foreach (var folder in folders)
{
Console.WriteLine($"OpenFoldersCommand: {folder.Name}, {folder.Path}");

FileItems.Add(folder.Path);

Check warning on line 178 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Dereference of a possibly null reference.

Check warning on line 178 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build ubuntu-latest

Dereference of a possibly null reference.

Check warning on line 178 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Dereference of a possibly null reference.

Check warning on line 178 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build windows-latest

Dereference of a possibly null reference.

Check warning on line 178 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Dereference of a possibly null reference.

Check warning on line 178 in samples/BehaviorsTestApplication/ViewModels/MainWindowViewModel.cs

View workflow job for this annotation

GitHub Actions / Build macos-latest

Dereference of a possibly null reference.
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@
</Interaction.Behaviors>
<TextBlock Text="Drop files here" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Background="Transparent" Padding="20" BorderThickness="1" BorderBrush="{DynamicResource SystemAccentColor}">
<Interaction.Behaviors>
<FilesDropBehavior Command="{Binding OpenFilesCommand}" />
</Interaction.Behaviors>
<TextBlock Text="Drop files here" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Border Background="Transparent" Padding="20" BorderThickness="1" BorderBrush="{DynamicResource SystemAccentColor}">
<Interaction.Behaviors>
<TextDropBehavior Command="{Binding GetClipboardTextCommand}" />
</Interaction.Behaviors>
<TextBlock Text="Drop text here" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ListBox ItemsSource="{Binding FileItems}" />
</StackPanel>
</UserControl>
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<Import Project="..\..\build\TrimmingEnable.targets" />

<ItemGroup>
<ProjectReference Include="..\Avalonia.Xaml.Interactions\Avalonia.Xaml.Interactions.csproj" />
<ProjectReference Include="..\Avalonia.Xaml.Interactivity\Avalonia.Xaml.Interactivity.csproj" />
</ItemGroup>

Expand Down
88 changes: 88 additions & 0 deletions src/Avalonia.Xaml.Interactions.DragAndDrop/DropBehaviorBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Xaml.Interactions.Core;

namespace Avalonia.Xaml.Interactions.DragAndDrop;

/// <summary>
///
/// </summary>
public abstract class DropBehaviorBase : InvokeCommandBehaviorBase
{
/// <summary>
///
/// </summary>
protected IDropHandler? Handler { get; set; }

/// <inheritdoc />
protected override void OnAttachedToVisualTree()
{
if (AssociatedObject is not null)
{
DragDrop.SetAllowDrop(AssociatedObject, true);
}
AssociatedObject?.AddHandler(DragDrop.DragEnterEvent, DragEnter);
AssociatedObject?.AddHandler(DragDrop.DragLeaveEvent, DragLeave);
AssociatedObject?.AddHandler(DragDrop.DragOverEvent, DragOver);
AssociatedObject?.AddHandler(DragDrop.DropEvent, Drop);
}

/// <inheritdoc />
protected override void OnDetachedFromVisualTree()
{
if (AssociatedObject is not null)
{
DragDrop.SetAllowDrop(AssociatedObject, false);
}
AssociatedObject?.RemoveHandler(DragDrop.DragEnterEvent, DragEnter);
AssociatedObject?.RemoveHandler(DragDrop.DragLeaveEvent, DragLeave);
AssociatedObject?.RemoveHandler(DragDrop.DragOverEvent, DragOver);
AssociatedObject?.RemoveHandler(DragDrop.DropEvent, Drop);
}

private void DragEnter(object? sender, DragEventArgs e)
{
Handler?.Enter(sender, e, null, null);
}

private void DragLeave(object? sender, RoutedEventArgs e)
{
Handler?.Leave(sender, e);
}

private void DragOver(object? sender, DragEventArgs e)
{
Handler?.Over(sender, e, null, null);
}

private void Drop(object? sender, DragEventArgs e)
{
Handler?.Drop(sender, e, null, null);
}

/// <summary>
///
/// </summary>
/// <param name="parameter"></param>
protected void ExecuteCommand(object? parameter)
{
if (IsEnabled != true || Command is null)
{
return;
}

if (AssociatedObject is not { IsVisible: true, IsEnabled: true })
{
return;
}

var resolvedParameter = ResolveParameter(parameter);

if (Command?.CanExecute(resolvedParameter) != true)
{
return;
}

Command.Execute(resolvedParameter);
}
}
43 changes: 43 additions & 0 deletions src/Avalonia.Xaml.Interactions.DragAndDrop/FilesDropBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Avalonia.Input;

namespace Avalonia.Xaml.Interactions.DragAndDrop;

/// <summary>
///
/// </summary>
public sealed class FilesDropBehavior : DropBehaviorBase
{
/// <summary>
///
/// </summary>
public FilesDropBehavior()
{
Handler = new FilesDropHandler(ExecuteCommand);
}

private sealed class FilesDropHandler(System.Action<object?> execute) : DropHandlerBase
{
public override bool Validate(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state)
{
return e.Data.Contains(DataFormats.FileNames);
}

public override bool Execute(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state)
{
if (!e.Data.Contains(DataFormats.FileNames))
{
return false;
}

var files = e.Data.GetFiles();
if (files is null)
{
return false;
}

execute(files);

return true;
}
}
}
43 changes: 43 additions & 0 deletions src/Avalonia.Xaml.Interactions.DragAndDrop/TextDropBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Avalonia.Input;

namespace Avalonia.Xaml.Interactions.DragAndDrop;

/// <summary>
///
/// </summary>
public sealed class TextDropBehavior : DropBehaviorBase
{
/// <summary>
///
/// </summary>
public TextDropBehavior()
{
Handler = new FilesDropHandler(ExecuteCommand);
}

private sealed class FilesDropHandler(System.Action<object?> execute) : DropHandlerBase
{
public override bool Validate(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state)
{
return e.Data.Contains(DataFormats.Text);
}

public override bool Execute(object? sender, DragEventArgs e, object? sourceContext, object? targetContext, object? state)
{
if (!e.Data.Contains(DataFormats.Text))
{
return false;
}

var text = e.Data.GetText();
if (text is null)
{
return false;
}

execute(text);

return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows.Input;
using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Xaml.Interactivity;

Expand All @@ -7,7 +8,7 @@ namespace Avalonia.Xaml.Interactions.Core;
/// <summary>
/// Invoke command behavior base class.
/// </summary>
public abstract class InvokeCommandBehaviorBase : StyledElementBehavior
public abstract class InvokeCommandBehaviorBase : StyledElementBehavior<Control>
{
/// <summary>
/// Identifies the <seealso cref="Command"/> avalonia property.
Expand Down