Iterated a bit on the dialog view model design, it now uses the UI dispatcher to ensure the Close() method is invoked in the UI thread
This commit is contained in:
		
							parent
							
								
									e11922ae4f
								
							
						
					
					
						commit
						bedd49ce17
					
				
					 3 changed files with 29 additions and 24 deletions
				
			
		| 
						 | 
				
			
			@ -62,25 +62,36 @@ namespace Nuclex.Avalonia.AutoBinding {
 | 
			
		|||
      if(dialogViewModel != null) {
 | 
			
		||||
        Window? viewAsWindow = view as Window;
 | 
			
		||||
        if(viewAsWindow != null) {
 | 
			
		||||
          EventHandler<DialogResultEventArgs> handler = (
 | 
			
		||||
            delegate(object sender, DialogResultEventArgs arguments) {
 | 
			
		||||
              viewAsWindow.Close(arguments.Result);
 | 
			
		||||
            }
 | 
			
		||||
          );
 | 
			
		||||
 | 
			
		||||
          dialogViewModel.Submitted += handler;
 | 
			
		||||
 | 
			
		||||
          // Does this help anything?
 | 
			
		||||
          // Without it, the view has a reference to the view model (via DataContext),
 | 
			
		||||
          // and the view model references the view (via event subscription), but this
 | 
			
		||||
          // shouldn't bother the .NET garbage collector at all.
 | 
			
		||||
          viewAsWindow.Closed += delegate(object sender, EventArgs arguments) {
 | 
			
		||||
            dialogViewModel.Submitted -= handler;
 | 
			
		||||
          };
 | 
			
		||||
          bindViewModelSubmitToDialogClose(viewAsWindow, dialogViewModel);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///   Convention binding for view models with a 'Submit' event,
 | 
			
		||||
    ///   closes the dialog when the view model fires the event
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="dialogWindow">Window the displays the dialog's UI</param>
 | 
			
		||||
    /// <param name="dialogViewModel">View model that has the 'Submit' event</param>
 | 
			
		||||
    private static void bindViewModelSubmitToDialogClose(
 | 
			
		||||
      Window dialogWindow, IDialogViewModel dialogViewModel
 | 
			
		||||
    ) {
 | 
			
		||||
      EventHandler<DialogResultEventArgs> handler = (
 | 
			
		||||
        delegate(object sender, DialogResultEventArgs arguments) {
 | 
			
		||||
          dialogWindow.Close(arguments.Result);
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      dialogViewModel.Submitted += handler;
 | 
			
		||||
 | 
			
		||||
      // Does this help anything?
 | 
			
		||||
      // Without it, the view has a reference to the view model (via DataContext),
 | 
			
		||||
      // and the view model references the view (via event subscription), but this
 | 
			
		||||
      // shouldn't bother the .NET garbage collector at all.
 | 
			
		||||
      dialogWindow.Closed += delegate (object sender, EventArgs arguments) {
 | 
			
		||||
        dialogViewModel.Submitted -= handler;
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
} // namespace Nuclex.Avalonia.AutoBinding
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,17 +26,17 @@ namespace Nuclex.Avalonia.ViewModels {
 | 
			
		|||
 | 
			
		||||
    /// <summary>Initializes a new dialog result event argument container</summary>
 | 
			
		||||
    /// <param name="result">Result the dialog should exit with</param>
 | 
			
		||||
    public DialogResultEventArgs(object result) {
 | 
			
		||||
    public DialogResultEventArgs(object? result) {
 | 
			
		||||
      this.result = result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>Result that should be returned from the dialog</summary>
 | 
			
		||||
    public object Result {
 | 
			
		||||
    public object? Result {
 | 
			
		||||
      get { return this.result; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>Result that should be returned from the dialog</summary>
 | 
			
		||||
    private readonly object result;
 | 
			
		||||
    private readonly object? result;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,6 @@ limitations under the License.
 | 
			
		|||
#endregion // Apache License 2.0
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
using Nuclex.Avalonia.ViewModels;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,11 +29,6 @@ namespace Nuclex.Avalonie.ViewModels {
 | 
			
		|||
    /// <summary>Indicates that the view should close</summary>
 | 
			
		||||
    event EventHandler<DialogResultEventArgs> Submitted;
 | 
			
		||||
 | 
			
		||||
    /// <summary>Indicates that the dialog should be closed</summary>
 | 
			
		||||
    /// <param name="dialogResult">Result the dialog should return</param>
 | 
			
		||||
    /// <returns>A task that finishes when the submit notification has been sent</returns>
 | 
			
		||||
    Task SubmitAsync(object? dialogResult = null);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
} // namespace Nuclex.Avalonie.ViewModels
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue