Address review
This commit is contained in:
Родитель
24b2482fef
Коммит
f2572c4b74
|
@ -161,7 +161,7 @@ Each sample is tagged with it's difficulty. The degree of difficulty describes h
|
||||||
| 🐔 Normal
|
| 🐔 Normal
|
||||||
| MVVM, Dialog, FileDialogs, TopLevel, Clipboard
|
| MVVM, Dialog, FileDialogs, TopLevel, Clipboard
|
||||||
|
|
||||||
| link:src\Avalonia.Samples\ViewInteraction\AdvancedMvvmDialogSample[Advanced Dialog Sample]
|
| link:src\Avalonia.Samples\ViewInteraction\DialogManagerSample[Dialog Manager Sample]
|
||||||
| 🐉 Hard
|
| 🐉 Hard
|
||||||
| MVVM, Dialog, FileDialogs, TopLevel, Clipboard, DialogManager
|
| MVVM, Dialog, FileDialogs, TopLevel, Clipboard, DialogManager
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Folder", "Solution
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MvvmDialogSample", "ViewInteraction\MvvmDialogSample\MvvmDialogSample.csproj", "{48432457-6A55-4D03-9D40-260CE8E06440}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MvvmDialogSample", "ViewInteraction\MvvmDialogSample\MvvmDialogSample.csproj", "{48432457-6A55-4D03-9D40-260CE8E06440}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdvancedMvvmDialogSample", "ViewInteraction\AdvancedMvvmDialogSample\AdvancedMvvmDialogSample.csproj", "{0BC90E92-D8B3-4C6D-8C47-BAF57CD73CBA}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DialogManagerSample", "ViewInteraction\DialogManagerSample\DialogManagerSample.csproj", "{0BC90E92-D8B3-4C6D-8C47-BAF57CD73CBA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{85B157B3-F701-4F75-B4F1-EC2287729480}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{85B157B3-F701-4F75-B4F1-EC2287729480}"
|
||||||
EndProject
|
EndProject
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
using AdvancedMvvmDialogSample.Services;
|
|
||||||
using ReactiveUI;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Input;
|
|
||||||
|
|
||||||
namespace AdvancedMvvmDialogSample.ViewModels
|
|
||||||
{
|
|
||||||
public class MainWindowViewModel : ViewModelBase
|
|
||||||
{
|
|
||||||
public MainWindowViewModel()
|
|
||||||
{
|
|
||||||
SelectFilesCommand = ReactiveCommand.CreateFromTask(SelectFilesAsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<string>? _SelectedFiles;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a list of Files
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<string>? SelectedFiles
|
|
||||||
{
|
|
||||||
get { return _SelectedFiles; }
|
|
||||||
set { this.RaiseAndSetIfChanged(ref _SelectedFiles, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ICommand SelectFilesCommand { get; }
|
|
||||||
|
|
||||||
private async Task SelectFilesAsync()
|
|
||||||
{
|
|
||||||
SelectedFiles = await this.OpenFileDialogAsync("Hello Avalonia");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace AdvancedMvvmDialogSample.ViewModels
|
|
||||||
{
|
|
||||||
public class ViewModelBase : ReactiveObject
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
<Application xmlns="https://github.com/avaloniaui"
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:AdvancedMvvmDialogSample"
|
xmlns:local="using:DialogManagerSample"
|
||||||
RequestedThemeVariant="Light"
|
RequestedThemeVariant="Light"
|
||||||
x:Class="AdvancedMvvmDialogSample.App">
|
x:Class="DialogManagerSample.App">
|
||||||
|
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<FluentTheme />
|
<FluentTheme />
|
|
@ -1,10 +1,10 @@
|
||||||
using AdvancedMvvmDialogSample.ViewModels;
|
using DialogManagerSample.ViewModels;
|
||||||
using AdvancedMvvmDialogSample.Views;
|
using DialogManagerSample.Views;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
namespace AdvancedMvvmDialogSample
|
namespace DialogManagerSample
|
||||||
{
|
{
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
До Ширина: | Высота: | Размер: 172 KiB После Ширина: | Высота: | Размер: 172 KiB |
|
@ -24,7 +24,7 @@
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.0.0" />
|
||||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0" />
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0" />
|
|
||||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" />
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0" />
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,8 +1,7 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.ReactiveUI;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace AdvancedMvvmDialogSample
|
namespace DialogManagerSample
|
||||||
{
|
{
|
||||||
internal class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
|
@ -17,7 +16,6 @@ namespace AdvancedMvvmDialogSample
|
||||||
public static AppBuilder BuildAvaloniaApp()
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
=> AppBuilder.Configure<App>()
|
=> AppBuilder.Configure<App>()
|
||||||
.UsePlatformDetect()
|
.UsePlatformDetect()
|
||||||
.LogToTrace()
|
.LogToTrace();
|
||||||
.UseReactiveUI();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
= Advanced MVVM Dialog Sample
|
= Dialog Manager Sample
|
||||||
// --- D O N ' T T O U C H T H I S S E C T I O N ---
|
// --- D O N ' T T O U C H T H I S S E C T I O N ---
|
||||||
:toc:
|
:toc:
|
||||||
:toc-placement!:
|
:toc-placement!:
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
|
|
||||||
// Write a short summary here what this examples does
|
// Write a short summary here what this examples does
|
||||||
This example will show you how to write a service that will help you to show dialogs in your MVVM application
|
This example will show you how to write a service (we will call it dialog manager) that will help you to show dialogs in your MVVM application
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,14 +24,14 @@ toc::[]
|
||||||
=== Difficulty
|
=== Difficulty
|
||||||
// Choose one of the below difficulties. You can just delete the ones you don't need.
|
// Choose one of the below difficulties. You can just delete the ones you don't need.
|
||||||
|
|
||||||
🐉 Hard 🐉
|
🐔 Normal 🐔
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=== Buzz-Words
|
=== Buzz-Words
|
||||||
|
|
||||||
// Write some buzz-words here. You can separate them by ", "
|
// Write some buzz-words here. You can separate them by ", "
|
||||||
MVVM, Dialog, FileDialogs, TopLevel, Clipboard, DialogManager
|
MVVM, Dialog, FileDialogs, TopLevel, Clipboard, DialogManager, CommunityToolkit.MVVM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,35 +39,37 @@ MVVM, Dialog, FileDialogs, TopLevel, Clipboard, DialogManager
|
||||||
|
|
||||||
We assume you already now how the MVVM pattern works and how dialogs, such as file dialogs, can be shown in general. You should also know what a https://docs.avaloniaui.net/docs/next/concepts/toplevel[[TopLevel\]]-control in Avalonia is and what it can be used for.
|
We assume you already now how the MVVM pattern works and how dialogs, such as file dialogs, can be shown in general. You should also know what a https://docs.avaloniaui.net/docs/next/concepts/toplevel[[TopLevel\]]-control in Avalonia is and what it can be used for.
|
||||||
|
|
||||||
|
NOTE: In this sample we will use the https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/[[CommunityToolkit.MVVM\]]-package which provides source generators for less boilerplate code. Please check out their docs if you want to learn more about this. (https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/generators/overview)
|
||||||
|
|
||||||
|
|
||||||
== The Solution : Use a DialogService to show a Dialog
|
== The Solution : Use a DialogService to show a Dialog
|
||||||
|
|
||||||
// This is where you explain the possible solution you provide in this sample.
|
// This is where you explain the possible solution you provide in this sample.
|
||||||
// If you have more than one option to solve the issue, use Approach 1, Approach 2, ...
|
// If you have more than one option to solve the issue, use Approach 1, Approach 2, ...
|
||||||
|
|
||||||
=== Step 1: Add a DialogService-class
|
=== Step 1: Add the DialogManager-class
|
||||||
|
|
||||||
In our project we add a folder called `Services`. Inside we will create a class called `DialogService` which inherits `AvaloniaObject`.
|
In our project we add a folder called `Services`. Inside we will create a class called `DialogManager`.
|
||||||
|
|
||||||
NOTE: We need to inherit `AvaloniaObject` because we want to add `Register` as an `AttachedProperty`
|
NOTE: We do not need to inherit `AvaloniaObject` even as we want to add `Register` as an `AttachedProperty` because Avalonia supports AttachedProperties on any object
|
||||||
|
|
||||||
Let's add a static `Dictionary` where we can store the registered mappings between the context (our `ViewModel`) and the `View` or `Control`, which we want to interact with.
|
Let's add a static `Dictionary` where we can store the registered mappings between the context (our `ViewModel`) and the `View` or `Control`, which we want to interact with.
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
public class DialogService : AvaloniaObject
|
public class DialogManager
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<object, Visual> RegistrationMapper =
|
private static readonly Dictionary<object, Visual> RegistrationMapper =
|
||||||
new Dictionary<object, Visual>();
|
new Dictionary<object, Visual>();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In the next step we add an https://docs.avaloniaui.net/docs/next/concepts/attached-property[[AttachedProperty]] to our dialog service, which we call `Register`. Later we can bind any object to this property from every available `Visual` in our `Views`.
|
In the next step we add an https://docs.avaloniaui.net/docs/next/concepts/attached-property[[AttachedProperty]] to our dialog manager, which we call `Register`. Later we can bind any object to this property from every available `Visual` in our `Views`.
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This property handles the registration of Views and ViewModel
|
/// This property handles the registration of Views and ViewModel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly AttachedProperty<object?> RegisterProperty = AvaloniaProperty.RegisterAttached<DialogService, Visual, object?>(
|
public static readonly AttachedProperty<object?> RegisterProperty = AvaloniaProperty.RegisterAttached<DialogManager, Visual, object?>(
|
||||||
"Register");
|
"Register");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -91,28 +93,28 @@ Now that we want to store or remove any new binding into our `Dictionary`, we ne
|
||||||
|
|
||||||
[source,cs]
|
[source,cs]
|
||||||
----
|
----
|
||||||
static DialogService()
|
static DialogManager()
|
||||||
{
|
{
|
||||||
RegisterProperty.Changed.Subscribe(RegisterChanged);
|
RegisterProperty.Changed.AddClassHandler<Visual>(RegisterChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RegisterChanged(AvaloniaPropertyChangedEventArgs<object?> e)
|
private static void RegisterChanged(Visual sender, AvaloniaPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Sender is not Visual sender)
|
if (sender is null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("The DialogService can only be registered on a Control");
|
throw new InvalidOperationException("The DialogManager can only be registered on a Visual");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregister any old registered context
|
// Unregister any old registered context
|
||||||
if (e.OldValue.Value != null)
|
if (e.OldValue != null)
|
||||||
{
|
{
|
||||||
RegistrationMapper.Remove(e.OldValue.Value);
|
RegistrationMapper.Remove(e.OldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register any new context
|
// Register any new context
|
||||||
if (e.NewValue.Value != null)
|
if (e.NewValue != null)
|
||||||
{
|
{
|
||||||
RegistrationMapper.Add(e.NewValue.Value, sender);
|
RegistrationMapper.Add(e.NewValue, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
@ -193,22 +195,23 @@ public static class DialogHelper
|
||||||
|
|
||||||
=== Step 4: Usage
|
=== Step 4: Usage
|
||||||
|
|
||||||
Now that we have our `DialogService` created, we can start to register the `View` for our `ViewModel`. Thanks to our attached property, we can simply do:
|
Now that we have our `DialogManager` created, we can start to register the `View` for our `ViewModel`. Thanks to our attached property, we can simply do:
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
<UserControl xmlns="https://github.com/avaloniaui"
|
<UserControl xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:dialog="using:AdvancedMvvmDialogSample.Services"
|
xmlns:services="using:DialogManagerSample.Services"
|
||||||
dialog:DialogService.Register="{Binding}">
|
services:DialogManager.Register="{Binding}">
|
||||||
<!-- Your content goes here -->
|
<!-- Your content goes here -->
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
And in the `ViewModel` we can use our extension methods anywhere. The below sample command will ask the user to select a bunch of files:
|
And in the `ViewModel` we can use our extension methods anywhere. The below sample command will ask the user to select a bunch of files. The command itself will be created using the source generators that the CommunityToolkit.MVVM-package provides.
|
||||||
|
|
||||||
[source,c#]
|
[source,c#]
|
||||||
----
|
----
|
||||||
|
[RelayCommand]
|
||||||
private async Task SelectFilesAsync()
|
private async Task SelectFilesAsync()
|
||||||
{
|
{
|
||||||
// Selected Files is a property of our ViewModel
|
// Selected Files is a property of our ViewModel
|
||||||
|
@ -216,16 +219,6 @@ private async Task SelectFilesAsync()
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
The command itself will be created in the constructor. However you can also use the source generators that the CommunityToolkit.MVVM-package provides.
|
|
||||||
|
|
||||||
[source,c#]
|
|
||||||
----
|
|
||||||
public MainWindowViewModel()
|
|
||||||
{
|
|
||||||
SelectFilesCommand = ReactiveCommand.CreateFromTask(SelectFilesAsync);
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
Now we can add the needed `List` and `Button` in our view:
|
Now we can add the needed `List` and `Button` in our view:
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
|
@ -6,42 +6,42 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace AdvancedMvvmDialogSample.Services
|
namespace DialogManagerSample.Services
|
||||||
{
|
{
|
||||||
public class DialogService : AvaloniaObject
|
public class DialogManager
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<object, Visual> RegistrationMapper =
|
private static readonly Dictionary<object, Visual> RegistrationMapper =
|
||||||
new Dictionary<object, Visual>();
|
new Dictionary<object, Visual>();
|
||||||
|
|
||||||
static DialogService()
|
static DialogManager()
|
||||||
{
|
{
|
||||||
RegisterProperty.Changed.Subscribe(RegisterChanged);
|
RegisterProperty.Changed.AddClassHandler<Visual>(RegisterChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RegisterChanged(AvaloniaPropertyChangedEventArgs<object?> e)
|
private static void RegisterChanged(Visual sender, AvaloniaPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Sender is not Visual sender)
|
if (sender is null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("The DialogService can only be registered on a Visual");
|
throw new InvalidOperationException("The DialogManager can only be registered on a Visual");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregister any old registered context
|
// Unregister any old registered context
|
||||||
if (e.OldValue.Value != null)
|
if (e.OldValue != null)
|
||||||
{
|
{
|
||||||
RegistrationMapper.Remove(e.OldValue.Value);
|
RegistrationMapper.Remove(e.OldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register any new context
|
// Register any new context
|
||||||
if (e.NewValue.Value != null)
|
if (e.NewValue != null)
|
||||||
{
|
{
|
||||||
RegistrationMapper.Add(e.NewValue.Value, sender);
|
RegistrationMapper.Add(e.NewValue, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This property handles the registration of Views and ViewModel
|
/// This property handles the registration of Views and ViewModel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly AttachedProperty<object?> RegisterProperty = AvaloniaProperty.RegisterAttached<DialogService, Visual, object?>(
|
public static readonly AttachedProperty<object?> RegisterProperty = AvaloniaProperty.RegisterAttached<DialogManager, Visual, object?>(
|
||||||
"Register");
|
"Register");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -102,7 +102,7 @@ namespace AdvancedMvvmDialogSample.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookup the TopLevel for the context
|
// lookup the TopLevel for the context
|
||||||
var topLevel = DialogService.GetTopLevelForContext(context);
|
var topLevel = DialogManager.GetTopLevelForContext(context);
|
||||||
|
|
||||||
if(topLevel != null)
|
if(topLevel != null)
|
||||||
{
|
{
|
|
@ -0,0 +1,27 @@
|
||||||
|
using DialogManagerSample.Services;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
|
namespace DialogManagerSample.ViewModels
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class MainWindowViewModel : ViewModelBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a list of Files
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private IEnumerable<string>? _SelectedFiles;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A command used to select some files
|
||||||
|
/// </summary>
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task SelectFilesAsync()
|
||||||
|
{
|
||||||
|
SelectedFiles = await this.OpenFileDialogAsync("Hello Avalonia");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace DialogManagerSample.ViewModels
|
||||||
|
{
|
||||||
|
public class ViewModelBase : ObservableObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,16 @@
|
||||||
<Window xmlns="https://github.com/avaloniaui"
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:vm="using:AdvancedMvvmDialogSample.ViewModels"
|
xmlns:vm="using:DialogManagerSample.ViewModels"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:dialog="using:AdvancedMvvmDialogSample.Services"
|
xmlns:services="using:DialogManagerSample.Services"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
x:Class="AdvancedMvvmDialogSample.Views.MainWindow"
|
x:Class="DialogManagerSample.Views.MainWindow"
|
||||||
x:DataType="vm:MainWindowViewModel"
|
x:DataType="vm:MainWindowViewModel"
|
||||||
x:CompileBindings="True"
|
x:CompileBindings="True"
|
||||||
dialog:DialogService.Register="{Binding}"
|
services:DialogManager.Register="{Binding}"
|
||||||
Icon="/Assets/avalonia-logo.ico"
|
Icon="/Assets/avalonia-logo.ico"
|
||||||
Title="AdvancedMvvmDialogSample">
|
Title="DialogManagerSample">
|
||||||
|
|
||||||
<Design.DataContext>
|
<Design.DataContext>
|
||||||
<vm:MainWindowViewModel/>
|
<vm:MainWindowViewModel/>
|
|
@ -1,6 +1,6 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
|
||||||
namespace AdvancedMvvmDialogSample.Views
|
namespace DialogManagerSample.Views
|
||||||
{
|
{
|
||||||
public partial class MainWindow : Window
|
public partial class MainWindow : Window
|
||||||
{
|
{
|
До Ширина: | Высота: | Размер: 416 KiB После Ширина: | Высота: | Размер: 416 KiB |
|
@ -302,7 +302,7 @@ image::_docs/result_1.png[Custom interaction sample]
|
||||||
|
|
||||||
There are more ways to show dialogs from the ViewModel, for example:
|
There are more ways to show dialogs from the ViewModel, for example:
|
||||||
|
|
||||||
* link:../AdvancedMvvmDialogSample[Dialog Service]
|
* link:../DialogManagerSample[DialogManager Service]
|
||||||
* https://github.com/AvaloniaCommunity/awesome-avalonia#mvvm--mvp--mvu[third party libs]
|
* https://github.com/AvaloniaCommunity/awesome-avalonia#mvvm--mvp--mvu[third party libs]
|
||||||
|
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче