Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TryCloseAsync(false) problem? #857

Open
Frenchy62620 opened this issue Apr 26, 2023 · 3 comments
Open

TryCloseAsync(false) problem? #857

Frenchy62620 opened this issue Apr 26, 2023 · 3 comments

Comments

@Frenchy62620
Copy link

Frenchy62620 commented Apr 26, 2023

I open a Dialog viewModel with WindowManager.

so inside the Dialog,
when i use TryCloseAsync(true) to close the Dialog, no problem,

but when i want to Cancel with TryCloseAsync(false) i have this error:

Message=DialogResult can be set only after Window is created and shown as dialog.

i am missingsomething??

the DailogViewModel is opened from the mainViewModel normlly with WindowManager

sorry for my english, hope you understant what i want to mean....

Regards
terry

@KasperSK
Copy link
Member

KasperSK commented May 3, 2023

Can you make a reproduction of this? Sounds like a bug.

@Frenchy62620
Copy link
Author

Frenchy62620 commented May 4, 2023

Hi KasperSK

its just the project WpfApp1

Bootstrapper:

using Caliburn.Micro;
using Ninject;
using System;
using System.Collections.Generic;
using System.Windows;
using WpfApp1.ViewModels;

namespace WpfApp1
{
    public class Bootstrapper : BootstrapperBase
    {
        private IKernel kernel;
        public Bootstrapper()
        {
            Initialize();
        }

        protected override void Configure()
        {
            kernel = new StandardKernel();
            kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
            kernel.Bind<IEventAggregator>().To<EventAggregator>().InSingletonScope();

            //var bindings0 = kernel.GetBindings(typeof(MyGridViewModel));
            //var bindings1 = kernel.GetBindings(typeof(MainViewModel));
        }
        protected override async void OnStartup(object sender, StartupEventArgs e)
        {
            await DisplayRootViewForAsync<MainViewModel>();
        }
        protected override object GetInstance(Type service, string key)
        {
            return kernel.Get(service);
        }
        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return kernel.GetAll(service);
        }
        protected override void BuildUp(object instance)
        {
            kernel.Inject(instance);
        }
    }
}

the mainViewModel

using Caliburn.Micro;
using Ninject;
using Ninject.Syntax;
using System.Dynamic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApp1.ViewModels
{
    public class MainViewModel : Screen
    {
        private readonly IResolutionRoot resolutionRoot;
        private readonly IEventAggregator eventAggregator;
        public MainViewModel(IResolutionRoot resolutionRoot, IEventAggregator eventAggregator)
        {
            this.resolutionRoot = resolutionRoot;
            this.eventAggregator = eventAggregator;
        }
        #region first stackpanel
        public async void DoModal()
        {
            //var vm = new MyDialogViewModel();
            var vm = resolutionRoot.Get<MyModalDialogViewModel>();
            var manager = resolutionRoot.Get<IWindowManager>();

            dynamic settings = new ExpandoObject();
            settings.WindowStyle = WindowStyle.ThreeDBorderWindow;
            settings.ShowInTaskbar = true;
            settings.Title = "COUCOU";
            settings.WindowState = WindowState.Normal;
            settings.ResizeMode = ResizeMode.CanMinimize;

            var result = await manager.ShowDialogAsync(vm, null, settings);

            MessageBox.Show($"The dialog returns with the result {result}");
        }

        public async void DoClose()
        {
            await TryCloseAsync();
        }
        #endregion

    }
}

MyModalDialogViewModel

using Caliburn.Micro;
using Ninject.Syntax;

namespace WpfApp1.ViewModels
{
    public class MyModalDialogViewModel : Screen
    {
        private readonly IResolutionRoot resolutionRoot;
        private readonly IEventAggregator eventAggregator;

        public MyModalDialogViewModel(IResolutionRoot resolutionRoot, IEventAggregator eventAggregator)
        {
            this.resolutionRoot = resolutionRoot;
            this.eventAggregator = eventAggregator;
        }
        public async void DoAccept()
        {
            await TryCloseAsync(true);
        }
        public async void DoCancel()
        {
            await TryCloseAsync(false);  // <------------------  ERROR here
        }
    }
}

the dialogView

<UserControl x:Class="WpfApp1.Views.MyModalDialogView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:cal="http://www.caliburnproject.org"
             xmlns:local="clr-namespace:WpfApp1.Views"
             mc:Ignorable="d" Background="Azure"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Width="500" Height="500" Background="AntiqueWhite">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Background="Aqua">
            <Button x:Name="DoAccept" Content="Accept" Padding="20" Margin="10" IsDefault="True" />
            <Button x:Name="DoCancel" Content="Cancel" Padding="20" Margin="10" IsCancel="True" />
        </StackPanel>
    </Grid>
</UserControl>

So when i cancel, i have the error each time

@Paciv
Copy link

Paciv commented Feb 9, 2024

Your button is set as IsCancel="True" and have no Command bind
In this case (see Button.cs#L277) the framework automatically executes a DialogCancelCommand which closes the window.

Hence you call to TryCloseAsync(false) tries to set the Window.DialogResult while the window is already considered as closed.

I believe you can remove your call to TryCloseAsync(false) as the framework command already set the DialogResult to false which triggers the window close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants