Coder Social home page Coder Social logo

avaloniautils / dialoghost.avalonia Goto Github PK

View Code? Open in Web Editor NEW
229.0 4.0 15.0 482 KB

AvaloniaUI control that provides a simple way to display a dialog with information or prompt the user when information is needed

License: MIT License

C# 100.00%
avalonia avaloniaui control xaml c-sharp c-sharp-library gui dialogs mvvm multi-platform

dialoghost.avalonia's Introduction

DialogHost.Avalonia

Avalonia DialogHost control that provides a simple way to display a dialog with information or prompt the user when information is required.

Dialogs in Avalonia have always been somewhat tricky. This implementation is designed to:

  • Provide correct styling
  • Allow any dialog to be constructed
  • Compatible with code-behind
  • Compatible with MVVM
  • Compatible with pure XAML
  • Work in applications with multiple windows

Dialogs are asynchronous so at some point you will have to deal with that in your code.

Getting started

  1. Install DialogHost.Avalonia nuget package

    dotnet add package DialogHost.Avalonia
  2. Add DialogHostStyles element to your app styles in App.axaml. See the example of App.axaml:

    <Application ...
        xmlns:dialogHostAvalonia="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
        ...>
        
        ...
        <Application.Styles>
            ...
            <dialogHostAvalonia:DialogHostStyles />
        </Application.Styles>
        ...
    </Application>

    For version below 0.7 instead of <dialogHostAvalonia:DialogHostStyles /> use StyleInclude:

    <StyleInclude Source="avares://DialogHost.Avalonia/Styles.xaml"/>
  3. Start using control

Using

The cornerstone of dialogs the DialogHost control. It’s a content control, meaning the underlying content over which the popup dialog will be displayed can be targeted; to a specific area of your app, or the entire Window content.

<Window ...
        xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
        ...
        Title="DialogHost.Demo">
    <dialogHost:DialogHost CloseOnClickAway="True">
        <dialogHost:DialogHost.DialogContent>
            <!-- put your dialog content here-->
        </dialogHost:DialogHost.DialogContent>
        <!-- put the content over which the dialog is shown here (e.g. your main window grid)-->
    </dialogHost:DialogHost>
</Window>

When the dialog is open, the underlying content will be dimmed and disabled.

preview

DialogHost.DialogContent (associated with DialogHost.DialogContentTemplate) is your typical XAML content object property for setting the content of your dialog. You can infer from this that you can use MVVM to bind content, but there are multiple ways of populating the content, showing the dialog, closing the dialog, and processing responses.

previewGif

Alternative way

  • HanumanInstitute.MvvmDialogs allows the use of MVVM design in a simplified way, with DialogHost support. If you opt for that syntax, you do not need most of the documentation below, and the DialogHost container is injected to window automatically at runtime.

Open Dialog Strategies

OpenDialogCommand

Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=materialDesign:DialogHost}, Path=OpenDialogCommand}"

ICommand, typically used on buttons, where DialogContent can be set via CommandParameter.

IsOpen

<dialogHost:DialogHost IsOpen="True" />

Dependency property, to be triggered from XAML, set from code-behind or via a binding. Content must be set in DialogHost.DialogContent.

DialogHost.Show

DialogHost.Show(viewOrModel);

Async/await based static API which can be used purely in code (for example from in a view model). Content can be passed directly to the dialog. Note that if you have multiple windows and multiple DialogHost instances you can set the DialogHost.Identifier property, and provide the identifier to the .Show(...) method to help find the required DialogHost.


Close Dialog Strategies

CloseDialogCommand

You can bind to the DialogHost's OpenDialogCommand:

Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=materialDesign:DialogHost}, Path=CloseDialogCommand}"

ICommand, typically used on buttons inside the dialog, where the command parameter will be passed along to the dialog response.

IsOpen

<dialogHost:DialogHost IsOpen="False" />

Dependency property, to be triggered from XAML, set from code-behind or via a binding.

DialogSession.Close

Via any of the methods for handling the opened event, you can get hold of the dialog session. This can be used to close a dialog via code:

var result = await DialogHost.Show(myContent, delegate(object sender, DialogOpenedEventArgs args)
{
    args.Session.Close(false);
});

or getting DialogSession

DialogHost.GetDialogSession("DialogHost.Identifier here")?.Close(false);

Handle Closing Event Strategies

The DialogClosingEventHandler delegate is key. It provides the parameter provided to DialogHost.CloseDialogCommand, and allows the pending close to be cancelled.

The following mechanisms allow handling of this event, via code-behind, MVVM practices, or just from the code API:

DialogHost.DialogClosing

<dialogHost:DialogHost DialogClosing="DialogHost_OnDialogClosing" />

Bubbling RoutedEvent, which could be used in code-behind.

DialogClosing.DialogClosingCallback

<dialogHost:DialogHost DialogClosingCallback="{Binding DialogClosingHandler}" />

Standard dependency property which enables the DialogClosingEventHandler implementation to be bound, typically from a view model.

DialogHost.Show

var result = await DialogHost.Show(viewOrModel, ClosingEventHandler);

The async response from this method returns the parameter provided when DialogHost.CloseDialogCommand was executed. As part of the Show() signature a DialogClosingEventHandler delegate can be provided to intercept the on-closing event, just prior to the close.

dialoghost.avalonia's People

Contributors

aldelaro5 avatar danipen avatar gigas002 avatar kirichenec avatar klorman avatar megazyz avatar mrxx99 avatar profix898 avatar skproch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

dialoghost.avalonia's Issues

Bug when mixing DialogContent and DataTemplates in a DialogHost instance in XAML ?

Pretty sure this was working on previous versions of the nuget package. I moved to 0.7.7 and now i'm seeing a wrong popup when attempting to select the dialog content vs a data template.
When using a data template using the 'Show' method then later attempting to select IsOpen shows the previous DataTemplate instead of the DialogContent.
Here is the snippet of my XAML:
<dialogHostAvalonia:DialogHost
x:Name="DialogHost"
IsOpen="{Binding CommandError, Converter={x:Static ObjectConverters.IsNotNull}}"
Identifier="MainDialogHost"
DialogClosingCallback="{Binding DialogClosingHandler}"
DialogMargin="16"
dialogHostAvalonia:DialogHostStyle.CornerRadius="8">
dialogHostAvalonia:DialogHost.DataTemplates












</dialogHostAvalonia:DialogHost.DataTemplates>

    <dialogHostAvalonia:DialogHost.DialogContent>
        <StackPanel Orientation="Vertical">

....
When the binding trigger the IsOpen it will show a previous DataTenmplate used befaore. If no DataTemplate was used before then the behavior is to show the proper dialog content.

Can anybody confirm if this is a valid bug?

Thanks in advance,

Documentation not included in NuGet

Documentation files are not included in the NuGet package.

There's this property to set in the project.

  <GenerateDocumentationFile>True</GenerateDocumentationFile>

The control already has a visual parent

Showing a Dialog with this; clicking away to close it, opening it a 2nd time, closing it again. On 3rd open, it throws an exception.

public async Task<object?> ShowDialogHostAsync(Control? owner, DialogHostSettings settings)
{
    var host = owner?.FindDescendantOfType<DialogHostAvalonia.DialogHost>()!;
    var closingHandler = settings.ClosingHandler ?? ((_, _) => { });
    return await DialogHostAvalonia.DialogHost.Show(settings.ContentViewModel!, host, closingHandler);
}
System.InvalidOperationException: The control already has a visual parent.
   at Avalonia.Visual.ValidateVisualChild(Visual c) in /_/src/Avalonia.Base/Visual.cs:line 646
   at Avalonia.Visual.<>c.<.ctor>b__19_0(Visual visual) in /_/src/Avalonia.Base/Visual.cs:line 145
   at Avalonia.Collections.AvaloniaList`1.InsertRange(Int32 index, IEnumerable`1 items) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 387
   at Avalonia.Controls.Panel.ChildrenChanged(Object sender, NotifyCollectionChangedEventArgs e) in /_/src/Avalonia.Controls/Panel.cs:line 127
   at Avalonia.Collections.AvaloniaList`1.NotifyAdd(T item, Int32 index) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 700
   at Avalonia.Collections.AvaloniaList`1.Add(T item) in /_/src/Avalonia.Base/Collections/AvaloniaList.cs:line 205
   at DialogHostAvalonia.DialogOverlayPopupHost.Show()
   at DialogHostAvalonia.DialogOverlayPopupHost.set_IsOpen(Boolean value)
   at DialogHostAvalonia.DialogHost.IsOpenPropertyChangedCallback(DialogHost dialogHost, Boolean newValue)
   at DialogHostAvalonia.DialogHost.set_IsOpen(Boolean value)
   at DialogHostAvalonia.DialogHost.ShowInternal(Object content, DialogOpenedEventHandler openedEventHandler, DialogClosingEventHandler closingEventHandler)
   at HanumanInstitute.MvvmDialogs.Avalonia.DialogHost.DialogHostApi.ShowDialogHostAsync(Control owner, DialogHostSettings settings) in /home/hanuman/GitHub/HanumanInstitute.MvvmDialogs/src/MvvmDialogs.Avalonia.DialogHost/DialogHostApi.cs:line 11

How to automatically open a View at startup?

I need to check some values at startup and after that I need to show or not show the view.
like this in View:

public MainViewModel()
{
    Task.Run(Startup);
}

private bool _isLogged;

private async Task Startup()
{
    if (_isLogged)
    {
    //don't show View
    }
    else
    {
        var loginView = new LoginViewControl();
        await DialogHost.DialogHost.Show(loginView, "MainDialogHost");
    }
}

For some reason, the View is not displayed at startup. Do you have any suggestions on how to do this?

Unable to open multiple dialogs one by one

When I call DialogHost.Show method this way to open dialogs one by one (this is a ViewModel of dialog to show):

public async Task<DialogResult> ShowAsync()
{
    await DialogHost.DialogHost.Show(this, DialogHostId);

    return (DialogResult)await DialogHost.DialogHost.Show(this, DialogHostId);
}

The second call shows dialog for a frame of a second, then it automatically closes, but the interface still looks like "blocked" and the only way to get rid of this is to rerun the program.
After digging inside of the second Show calls, I've found out, that it throws an exception in DialogHost.cs class after list.Count == 0 check on this method:

private static DialogHost.DialogHost GetInstance(string? dialogIdentifier)
{
  if (DialogHost.DialogHost.LoadedInstances.Count == 0)
    throw new InvalidOperationException("No loaded DialogHost instances.");
  List<DialogHost.DialogHost> list = DialogHost.DialogHost.LoadedInstances.Where<DialogHost.DialogHost>((Func<DialogHost.DialogHost, bool>) (dh => dialogIdentifier == null || object.Equals((object) dh.Identifier, (object) dialogIdentifier))).ToList<DialogHost.DialogHost>();
  if (list.Count == 0)
    throw new InvalidOperationException("No loaded DialogHost have an Identifier property matching dialogIdentifier ('" + dialogIdentifier + "') argument.");
  return list.Count <= 1 ? list[0] : throw new InvalidOperationException("Multiple viable DialogHosts. Specify a unique Identifier on each DialogHost, especially where multiple Windows are a concern.");
}

I should also mention, that if I manually set some delay between dialog's calls this way:

public async Task<DialogResult> ShowAsync()
{
    await DialogHost.DialogHost.Show(this, DialogHostId);

    await Task.Delay(1);

    return (DialogResult)await DialogHost.DialogHost.Show(this, DialogHostId);
}

Then it works as expected.

Empty dialog content's visuals

I've written a simple program with avalonia's mvvm template. Here's my MainWindowView.xaml code:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:DialogHostTest.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:dialogHost="clr-namespace:DialogHost;assembly=DialogHost.Avalonia"
        mc:Ignorable="d"
        Width="300"
        Height="200"
        x:Class="DialogHostTest.Views.MainWindow"
        Icon="/Assets/avalonia-logo.ico"
        Title="DialogHostTest">

    <Design.DataContext>
        <vm:MainWindowViewModel/>
    </Design.DataContext>

  <dialogHost:DialogHost Identifier="{Binding DialogHostId}">
    <Button VerticalAlignment="Stretch"
            HorizontalAlignment="Stretch"
            VerticalContentAlignment="Center"
            HorizontalContentAlignment="Center"
      Content="Show dialog" Command="{Binding ShowDialogAsync}"/>
    
  </dialogHost:DialogHost>

</Window>

And here's MainViewModel's code:

using System.Threading.Tasks;

namespace DialogHostTest.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        public static string DialogHostId => "MainDialogHost";

        public async Task ShowDialogAsync()
        {
            var result = await MessageBoxViewModel.ShowAsync("Test message!", DialogHostId);
        }
    }
}

I want to show message box on this button's click, so I wrote a simple UserControl and ViewModel for it.

View's code:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="DialogHostTest.Views.MessageBoxView">

  <Grid RowDefinitions="*,10,*"
        ColumnDefinitions="*,10,*">
    <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
               Text="{Binding Message}"/>
    <Button Grid.Row="2" Grid.Column="0"
            Content="OK"
            Command="{Binding OkButton}"/>
    <Button Grid.Row="2" Grid.Column="2"
            Content="Cancel"
            Command="{Binding CancelButton}"/>
  </Grid>

</UserControl>

ViewModel's code:

using System.Threading.Tasks;
using ReactiveUI;
using DialogHostTest.Enums;

namespace DialogHostTest.ViewModels
{
    public class MessageBoxViewModel : ViewModelBase
    {
        private string _message;

        public string Message 
        {
            get => _message;
            set => this.RaiseAndSetIfChanged(ref _message, value);
        }

        public DialogResult DialogResult { get; set; }

        public MessageBoxViewModel(string message)
        {
            Message = message;
        }

        public void OkButton()
        {
            DialogResult = DialogResult.OK;

            CloseDialog(MainWindowViewModel.DialogHostId);
        }

        public void CancelButton()
        {
            DialogResult = DialogResult.Cancel;

            CloseDialog(MainWindowViewModel.DialogHostId);
        }

        public void CloseDialog(string dialogHostId)
        {
            DialogHost.DialogHost.Close(dialogHostId, DialogResult);
        }
    
        public static async Task<DialogResult> ShowAsync(string message, string dialogHostId)
        {
            var res = await DialogHost.DialogHost.Show(new MessageBoxViewModel(message), dialogHostId);

            return (DialogResult)res;
        }
    }
}

But when I click on the button, I can't see the desired UserControl:

What I see

That's how it looks in VS's designer:

How it looks in VS's designer

Though I must say, that when I click on areas, where buttons should be, the dialog closes successfully, and I receive desired DialogResult.

Compatibility with Avalonia 11.1?

Hi,

While testing with danipen/TextMateSharp#57 (comment) in the Avalonia 11.1 previews, I noticed that an about box using DialogHost.Avalonia didn't work correctly - the dialog appeared but didn't disappear when closed, just hung about over the top of the background.

As a test I tried updating the demo application from this repository to the Avalonia 11.1 Beta 1 release and saw there are problems there as well
dh

There are also some warnings in the debugger output:

[Binding]An error occurred binding 'OverlayBackground' to '': 'Could not convert 'DialogHostDemo.ViewModels.MainWindowViewModel' (DialogHostDemo.ViewModels.MainWindowViewModel) to 'Avalonia.Media.IBrush'.' (DialogHost #25747420)
[Binding]An error occurred binding 'Background' to '': 'Could not convert 'DialogHostDemo.ViewModels.MainWindowViewModel' (DialogHostDemo.ViewModels.MainWindowViewModel) to 'Avalonia.Media.IBrush'.' (DialogHost #25747420)

Thanks.

Popup spawn in the wrong place when he is inside of a Viewbox

Describe
If DialogHost control inside of a ViewBox control and if after running the app resize window along two axes(x,y), then popup will spawn in the wrong place (not in a center of the parent conrol). By default, without resizing popup spawns in center of the parent conrol.

Perhaps this behavior is correct?

Expected behavior
After resizing the window, popup will spawns in the center of a parent conrol.

Details
ViewboxIssue

If you override the OverlayLayer control (add HorizontalAlignment=Center, VerticalAlignment=Center, as showed below, then problem is solved:
image

Repro
https://github.com/SergeyV17/DialogHostViewBoxIssueRepro

Material.Avalonia dark theme issue

Background not changed with Material.Avalonia:

Reception.App.2022-11-06.01-32-18.mp4

Fixed it by this code:

<Style Selector="dialogHost|DialogHost Border#PART_ContentBackground">
    <Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
</Style>

SystemControlBackgroundAltHighBrush => MaterialDesignPaper

  • Avalonia 0.10.18
  • Material.Avalonia 3.0.0-avalonia10-preview2

Can't use dialoghost after updating to 0.7.9

I've just updated Avalonia and DialogHost in my project. And after this update dialoghost doesn't seem to work. I've included DialogHostStyles in App.axaml. But I get exception System.InvalidOperationException: Collection was modified; enumeration operation may not execute
Even if I leave the dialoghost empty, I still get this exception. Can anyone please help with this?

Bug when starting and running under net framework 4.7.2

在 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
在 System.Collections.Generic.Dictionary2.KeyCollection.Enumerator.MoveNext() 在 System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
在 System.Reactive.Disposables.CompositeDisposable.ToList(IEnumerable1 disposables) 在 System.Reactive.Disposables.CompositeDisposable..ctor(IEnumerable1 disposables)
在 DialogHostAvalonia.Utilities.MultiDynamicResourceExtension.MultiDynamicResourceObservable..ctor(IEnumerable`1 observables, Object defaultValue)
在 DialogHostAvalonia.Utilities.MultiDynamicResourceExtension.Avalonia.Data.IBinding.Initiate(AvaloniaObject target, AvaloniaProperty targetProperty, Object anchor, Boolean enableDataValidation)
在 Avalonia.Styling.Setter.SetBinding(StyleInstance instance, AvaloniaObject target, IBinding binding)
在 Avalonia.Styling.Setter.Instance(IStyleInstance instance, StyledElement target)
在 Avalonia.Styling.StyleBase.Attach(StyledElement target, IStyleActivator activator, FrameType type)
在 Avalonia.Styling.ControlTheme.TryAttach(StyledElement target, FrameType type)
在 Avalonia.StyledElement.ApplyControlTheme(ControlTheme theme, FrameType type)
在 Avalonia.StyledElement.ApplyControlTheme()
在 Avalonia.StyledElement.ApplyStyling()
在 Avalonia.StyledElement.EndInit()

Feature Request : Dialog Alignment

I use DialogHost in my SukiUI library to show dialogs, and by the way thank you for you work 👍
Recently I made some Mobile Controls which requires to show a dialog at the bottom :

https://github.com/kikipoulet/SukiUI/wiki/3.-Mobile-Controls#mobile-picker

To make that I used some very ugly code in a very ugly fork to create a new parameter and simply show the dialog at bottom with this code change :

var verticalMargin = (parameters.AnchorRectangle.Height - parameters.Size.Height) / 1.05;

in the DialogPopupPositioner class.
The problem is that it messed up all my dependencies with avalonia 0.10 to 0.11 migration, and the only solution for me was to come at the DialogHost 0.6.0 nuget package, which basically saved me 👍

So .. could it be possible to add a "VerticalAlignment" parameter in the dialoghost control ? :-)

Popup focus issues

I found a couple of issues:

  1. The focus is drawn with some unwanted offset.
  2. The focus should be restricted to the Popup.
popup.mp4

If someone gives me some clues about how to fix it, I can try to create a PR.

`Datagrid` unable to input text in `DialogHost`

I put a datagrid in dialoghost, but it can be edit

<dialog:DialogHost DisableOpeningAnimation="True" Identifier="Main">
    <dialog:DialogHost.DataTemplates>
        <DataTemplate DataType="vm:AddAskModel">

            ....

            <DataGrid
                Width="200"
                Height="150"
                Margin="5,0,0,0"
                AutoGenerateColumns="False"
                CanUserResizeColumns="True"
                CanUserSortColumns="False"
                ItemsSource="{Binding ServerList}">
                <DataGrid.Columns>
                    <DataGridTextColumn
                        Binding="{Binding Name}"
                        Header="执行的服务器"
                        IsReadOnly="False" />
                </DataGrid.Columns>
            </DataGrid>
        </DataTemplate>
    </dialog:DialogHost.DataTemplates>

....

GIF

To be precise, it is impossible to input text after selecting it

Can it be used purely from code-behind?

I'm exploring to include support for DialogHost in MvvmDialogs. What I'm seeing is that you designed it to already support MVVM but in a different way.

Can it still be used purely from code-behind, to integrate into MvvmDialogs architecture?

What I'll want is to fill in this code.

public async Task<object?> ShowDialogHostAsync<T>(Control? owner)
    where T : Control, new()
{
    return await DialogHost.Show(new T());
}

How do I set the owner?

I could have a standard method to display any UserControl, then extensions methods calling it like MessageBox and InputText that display preset UserControls. If I pass the UserControl instance, then I can also set initial properties. Does that structure make sense?

Edit: I think I'm getting somewhere with this. Then I just need to create UserControls for the dialogs and it should work?

public async Task<object?> ShowDialogHostAsync<T>(Control? owner, T content, DialogClosingEventHandler? closingHandler = null)
    where T : Control
{
    var host = owner?.FindDescendantOfType<DialogHost>()!;
    closingHandler ??= (_, _) => { };
    return await DialogHost.Show(content, host, closingHandler);
}

Animations performance

Running the demo in release mode results in a noticeable lag when opening a dialog with animations. It seems to get better after a few opens, probably because of some Avalonia caching.

Is this behavior expected/noticeable on other machines? I don't have the best PC in the world, but I would assume these animations should not be that compute intensive.

I may look into optimizing it in the future, but I'm not very proficient in Avalonia so if someone wants to pick it up go ahead. For now I will opt into dialog without zoom in animation, which mitigates the issue.

Support Avalonia 11 RC?

Avalonia has reached the 11.0 RC candidate: AvaloniaUI/Avalonia#11593

If I upgrade the project to use Avalonia 11.0.0-rc1.1, I get these errors:

1>C:\dev\DialogHost.Avalonia\DialogHost.Avalonia\DialogOverlayPopupHost.axaml.cs(88,86,88,93): error CS0122: 'IManagedPopupPositionerPopup.Screens' is inaccessible due to its protection level
1>C:\dev\DialogHost.Avalonia\DialogHost.Avalonia\DialogOverlayPopupHost.axaml.cs(97,43,97,73): error CS0122: 'IManagedPopupPositionerPopup.ParentClientAreaScreenGeometry' is inaccessible due to its protection level
1>C:\dev\DialogHost.Avalonia\DialogHost.Avalonia\DialogOverlayPopupHost.axaml.cs(114,45,114,52): error CS0122: 'IManagedPopupPositionerPopup.Scaling' is inaccessible due to its protection level
1>C:\dev\DialogHost.Avalonia\DialogHost.Avalonia\DialogOverlayPopupHost.axaml.cs(101,43,101,56): error CS0122: 'IManagedPopupPositionerPopup.MoveAndResize(Point, Size)' is inaccessible due to its protection level

DialogHostStyle.SetBorderThickness throws System.ArgumentException

Setting BorderThickness using DialogHostStyle.SetBorderThickness method throws a System.ArgumentException. This is because the type of the value argument must be Thickness not double.

Steps to reproduce:

var dialogContent = new DialogContent();

DialogHost.Show(dialogContent, (o, args) =>
{
    if (o is DialogHost dialogHost)
    {
        DialogHostStyle.SetBorderThickness(dialogHost, 10);
    }
}, (o, args) =>
{
    //    
});

Exception details:

System.ArgumentException: Invalid value for Property 'BorderThickness': '10' (System.Double)
   at Avalonia.StyledProperty`1.ShouldSetValue(AvaloniaObject target, Object value, TValue& converted)
   at Avalonia.StyledProperty`1.RouteSetValue(AvaloniaObject target, Object value, BindingPriority priority)
   at Avalonia.AvaloniaObject.SetValue(AvaloniaProperty property, Object value, BindingPriority priority)
   at DialogHostAvalonia.DialogHostStyle.SetBorderThickness(DialogHost element, Double value)

This works:

dialogHost.SetValue(DialogHostStyle.BorderThicknessProperty, (object) new Thickness(10));

DialogHost not shown when Dialog Content contains ListBox

I have a minimal sample project where the DialogHost content contains a ListBox and a Button, when the ListBox is there the Dialog is not shown, if the ListBox is not there the Dialog is shown properly.

You can check with the project AvaloniaMatrixInvertIssue_v11 here:
https://github.com/Mrxx99/AvaloniaDialogHostAndAsyncImageLoaderIssue

Just lunch the project and click the "Show Dialog" button -> dialog will not show
then stop, remove or replace the ListBox and try again -> now it will work

(you can ignore the other projects and the async image loader in the repo as there was initial an issue when both were used together with avalonia 11 preview6)

AlignmentDialogPopupPositioner does not support Stretch alignment

Setting AlignmentDialogPopupPositioner.HorizontalAlignment or VerticalAlignment to Stretch does not have an effect, the dialog gets aligned to the top left corner.

Sample code:

<dialogHostAvalonia:DialogHost CloseOnClickAway="True" IsOpen="True">
    <dialogHostAvalonia:DialogHost.PopupPositioner>
        <positioners:AlignmentDialogPopupPositioner VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
    </dialogHostAvalonia:DialogHost.PopupPositioner>
    <dialogHostAvalonia:DialogHost.DialogContent>
        <Border Background="Yellow" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <TextBlock>Dialog content</TextBlock>
        </Border>
    </dialogHostAvalonia:DialogHost.DialogContent>
    Welcome to Avalonia!
</dialogHostAvalonia:DialogHost>

I have a commit that fixes this, but I am not sure if it is a valid solution or just a hack: 4f0a7fd

AlignmentDialogPopupPositioner margin doesn't work when align top left corner

<!-- It's fine -->
<!--<dialogHostAvalonia:DialogHost.PopupPositioner>
	<positioners:AlignmentDialogPopupPositioner VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="20"/>
</dialogHostAvalonia:DialogHost.PopupPositioner>-->
			
<dialogHostAvalonia:DialogHost.PopupPositioner>
	<positioners:AlignmentDialogPopupPositioner VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20"/>
</dialogHostAvalonia:DialogHost.PopupPositioner>

image

#16

The Margin property doesn't work when I try to align the upper left corner, so I forked the latest code and tried it out and found that everything works fine when aligning the small right corner, but not when aligning to the upper left corner. thanks

Crashes using Avalonia 11 nightly

I'm working with Avalonia 11.0.0-preview5 + DialogHost 0.7.0-preview4. My application style contains these declarations:

<Application.Styles>
	<FluentTheme/>
	<StyleInclude Source="avares://DialogHost.Avalonia/Styles.xaml"/>
	<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>

It works fine, but once I upgrade Avalonia to the nightly build 11.0.999-cibuild0031207-beta, the app crashes at startup with error:

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'DialogHostAvalonia.DialogOverlayPopupHost' threw an exception.
  Source=DialogHost.Avalonia
  StackTrace:
   at CompiledAvaloniaXaml.!AvaloniaResources.Populate:/DialogOverlayPopupHost.axaml(IServiceProvider , Styles )
   at CompiledAvaloniaXaml.!AvaloniaResources.Build:/DialogOverlayPopupHost.axaml(IServiceProvider )
   at CompiledAvaloniaXaml.!AvaloniaResources.Populate:/Styles.xaml(IServiceProvider , Styles )
   at CompiledAvaloniaXaml.!AvaloniaResources.Build:/Styles.xaml(IServiceProvider )
   at GateTrainer.App.!XamlIlPopulate(IServiceProvider , App ) in C:\Users\miste\Projects\Spark\repo\GateTrainer\GateTrainer\GateTrainer\App.axaml:line 11
   at GateTrainer.App.!XamlIlPopulateTrampoline(App )
   at GateTrainer.App.Initialize() in C:\Users\miste\Projects\Spark\repo\GateTrainer\GateTrainer\GateTrainer\App.axaml.cs:line 14
   at Avalonia.AppBuilder.Setup()
   at Avalonia.AppBuilder.SetupWithLifetime(IApplicationLifetime lifetime)
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode)
   at GateTrainer.Desktop.Program.Main(String[] args) in C:\Users\miste\Projects\Spark\repo\GateTrainer\GateTrainer\GateTrainer.Desktop\Program.cs:line 22

  This exception was originally thrown at this call stack:

Inner Exception 1:
MissingMethodException: Method not found: 'Avalonia.StyledProperty`1<!!1> Avalonia.AvaloniaProperty.Register(System.String, !!1, Boolean, Avalonia.Data.BindingMode, System.Func`2<!!1,Boolean>, System.Func`3<Avalonia.AvaloniaObject,!!1,!!1>, System.Action`2<Avalonia.AvaloniaObject,Boolean>)'.

How to set up the dialog position?

Hi.
I'm trying to use the DialogHost.Avalonia.
It'is working fine, opening the dialog centered on the screen.
How can I show the dialog at the bottom of the screen?
Thank you.

Does not work correctly on iOS

I'm using DialogHost.Avalonia 0.7.7 for an app project targeting both Android and iOS.
Avalonia framework version is 11.0.6 and .NET version is 7.

Please check the attached sample project. It simply opens a message dialog (MessageDialog.xaml) when clicking the Button.

Running in Debug mode, it works as expected on Android 11. Instead on iOS (different devices from version 15.8 to 16.2) the popup does not open, or it takes a very long time.

Sorry but I cannot test in Release mode as for now, so I cannot tell you if this is related to a particular Configuration.

PopupTest.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.