TheRealVira TheRealVira - 22 days ago 11
C# Question

How to trigger the setter of a property of an enum when passing as parameter?

Imagine you have a property and a private field:


private MessageBoxResult doNotUseMe_Result;

public MessageBoxResult MyResult
{
get { return doNotUseMe_Result; }
set
{
doNotUseMe_Result = value;
}
}


MessageBoxResult is an enum which is used to get the result of a MessageBox (WPF). Nevertheless I am getting problems when passing
MyResult
to methods, because it automatically uses the value type of the enum and changed results are getting collected by the
GC
, because it is now a totally new variable which is specified inside the scope of my method (
TaskBasedShow
)...

My current setup:


public delegate void OnResult(MessageBoxResult res);

private MessageBoxResult doNotUseMe_Result;

public MainWindow()
{
InitializeComponent();

OnRes += MessageBox_OnRes;

TaskBasedShow("My message", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Question, MyResult);
}

public MessageBoxResult MyResult
{
get { return doNotUseMe_Result; }
set
{
doNotUseMe_Result = value;
OnRes?.Invoke(value);
}
}


public void TaskBasedShow(string message, string caption, MessageBoxButton buttons,
MessageBoxImage image, MessageBoxResult resultprop)
{
Task.Factory.StartNew(() => { resultprop = MessageBox.Show(message, caption, buttons, image); });
}

/// <summary>
/// Is getting triggered after the user pressed a button.
/// </summary>
/// <param name="res">The pressed button.</param>
private void MessageBox_OnRes(MessageBoxResult res)
{
MessageBox.Show(res.ToString());
}


public event OnResult OnRes;


I do have read the following documentations:



but it seems like
enum
does not provide a
Set(value)
method.




The problem:



When setting the variable of a property of an enum (inside a mothod), the setter does not get triggered and therefore my custom events.

What it should do:



It should trigger
OnRes
when setting the property because my setter is getting triggered and therefore my subscribers of the
OnResult
event. Working example:


public MainWindow()
{
InitializeComponent();

OnRes += MessageBox_OnRes;

MyResult = MessageBoxResult.Cancel;
}


It will than open another messagebox displaying "Cancel".

Note:



One solution would be using the property inside
TaskBasedShow
:


Task.Factory.StartNew(() => { MyResult = MessageBox.Show(message, caption, buttons, image); });


because it now uses the reference type and not the passed value type.

Answer

You should use a callback to get the result value back

public async void TaskBasedShow( 
    string message, 
    string caption, 
    MessageBoxButton buttons,
    MessageBoxImage image, 
    Action<MessageBoxResult> resultCallback)
{
    var result = await Task.Run(() => MessageBox.Show(message, caption, buttons, image ) );
    resultCallback( result );
}

and call it like

TaskBasedShow(
    "My message", 
    "My caption", 
    MessageBoxButton.YesNo, 
    MessageBoxImage.Question, 
    r => MyResult = r );
Comments