Custom Dialog and DialogResust

130 views
Skip to first unread message

Damian Suess

unread,
Feb 6, 2017, 4:37:21 AM2/6/17
to Eto.Forms
Recently made the switch to Eto.Forms in favor of other frameworks, however I'm fumbling with the fundamental Dialog. Ive created a custom dialog to display app load errors and wantto return the simple Yes/No or Close depending on severity, however I cannot return DialogResult.

There is a previous post which did perform this, however usage of close via "Close(DialogResult)" has heed removed? The goal is to allow the parent to handle the return code, not within like the Eto.Test sample does. Any thoughts?

If this is not possible anymore, is there a reason why?

Thank you,
Damian

Message has been deleted

Damian Suess

unread,
Feb 6, 2017, 6:49:46 AM2/6/17
to Eto.Forms
Ok, wow after beating my head for a few hours I finally found it. Do you mind if if the following gets documented for v2.3 of Eto on the GitHub wiki pages? Thanks to another search and this time for, "AbortButton" and not DialogResult (or deprecated Result property) a hint was found under the unlikely source, WebViewSelection sample.

So here it goes, making use of DialogResult with a custom Dialog box.

### Note:
1) My project is using Eto's XAML feature to create the UI.
2) Below we're assuming we're calling the dialog from some regular Eto.Form's button.
3) Inputs

### Breakdown:
* Our custom dialog inherits from ``Dialog<DialogResult>`` not just, ``Dialog``.
* Calling our dialog you must define as such
```
Dialog<DialogResult> dialog = new Views.DialogLoadError(DialogButtonType.YesNo);
DialogResult result = dialog.ShowModal(this);
```


# Sample Code:

## MainForm.cs
```
// ------------------------------------
// MainForm.cs
// Call our custom dialog
using System;
using Eto.Forms;
using Xeno.Sandbox.EtoForms.Views;

namespace Xeno.Sandbox.EtoForms
{
public partial class MainForm
{
// ... Initialize & draw our MainForm : Eto.Forms.Form

private void BtnTestDialog_Clicked(object sender, EventArgs e)
{
// Default to "Close" button only
//Dialog<DialogResult> dialog = new Views.AddinLoadError();
//Dialog<DialogResult> dialog = new Views.AddinLoadError(Views.DialogButtonType.Close);

Dialog<DialogResult> dialog = new Views.AddinLoadError(Views.DialogButtonType.YesNo);

DialogResult result = dialog.ShowModal(this);
switch (result)
{
case DialogResult.Yes: MessageBox.Show("Yes"); break;
case DialogResult.No: MessageBox.Show("No"); break;
case DialogResult.Ok:
default:
MessageBox.Show("OK"); break;
}
//this.ShowDialogAsync(dialog, this);
}
}
}
```

## DialogLoadError.xeto
Below uses the basic elements required by dialog. Make your own more pretty

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Dialog
xmlns="http://schema.picoe.ca/eto.forms"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title=""
Maximizable="False">

<StackLayout>

<Label Text="The following add-ins could not be started:" />
<Label x:Name="LblMessage" Text="Custom message.." />

<StackLayoutItem HorizontalAlignment="Right">
<StackLayout Orientation="Horizontal" Spacing="5">
<Button ID="BtnYes" Text="&amp;Yes" Visible="True" Click="BtnYes_Click" />
<Button ID="BtnNo" Text="No" Visible="True" Click="BtnNo_Click" />
<Button ID="BtnClose" Text="C&amp;lose" Visible="False" Click="BtnClose_Click" />
</StackLayout>
</StackLayoutItem>
</StackLayout>

</Dialog>
```


## DialogLoadError.xeto.cs
This is just a sample; an Enum passed in is more suitable than an integer.

```cs
// -----------------------------------------
// DialogLoadError.xeto.cs
// Our custom dialog with DialogResult codes
using System;
using Eto.Forms;
using Eto.Serialization.Xaml;

namespace Xeno.Sandbox.EtoForms.Views
{
public enum DialogButtonType
{
Close,
YesNo
}

public class DialogLoadError : Dialog<DialogResult>
{
protected Button BtnNo { get; set; }
protected Button BtnYes { get; set; }
protected Button BtnClose { get; set; }
protected Label LblMessage { get; set; }

/// <summary>Default constructor, show warning message</summary>
public DialogLoadError() : this(DialogButtonType.Close) { }

/// <summary>Display dialog box</summary>
public DialogLoadError(DialogButtonType buttonType)
{
XamlReader.Load(this);
this.Title = "Application Issue";

switch(buttonType)
{
case DialogButtonType.Close:
LblMessage.Text = "Only show, Close";
BtnYes.Visible = false;
BtnNo.Visible = false;
BtnClose.Visible = true;

this.DefaultButton = BtnClose;
break;

case DialogButtonType.YesNo:
default:
LblMessage.Text = "Lite error. Show Yes, No";
BtnYes.Visible = true;
BtnNo.Visible = true;
BtnClose.Visible = false;

this.DefaultButton = BtnYes;
this.AbortButton = BtnNo;
break;
}
}

protected void BtnYes_Click(object sender, EventArgs e)
{
this.Close(DialogResult.Yes);
}

protected void BtnNo_Click(object sender, EventArgs e)
{
Close(DialogResult.No);
}

protected void BtnClose_Click(object sender, EventArgs e)
{
Close(DialogResult.Ok);
}
}
}
```

curtis

unread,
Feb 6, 2017, 3:21:23 PM2/6/17
to Eto.Forms
Hey Damian,

I'm glad you found the answer.  The Dialog<T> is useful as you can return custom values, not just DialogResult. For example, if you have a custom enum, or if you just want to return a bool, it works a lot better.  E.g.

var dialog = new Dialog<bool>();
var okButton = new Button { Text = "Yes" };
okButton
.Click += (sender, e) => dialog.Close(true);
dialog
.Content = new TableLayout("Some Content", okButton);

if (dialog.ShowModal())
{
 
// do something when user clicks the yes button
}


I've added some links to the different types of windows on the wiki here, which should hopefully help others find this in the future.

If you want to use this from xaml, this should work: <Dialog x:TypeArguments="{x:Boolean}"></Dialog>

Hope this helps!
Curtis.

Damian Suess

unread,
Feb 6, 2017, 8:45:05 PM2/6/17
to Eto.Forms
Curtis, you're the man. Thank you for the kind followup and quick response with the xaml pointer.

Keep up the great work!

Reply all
Reply to author
Forward
0 new messages