如何在作为参数传递时触发枚举属性的setter

本文关键字:枚举 属性 setter 参数传递 | 更新日期: 2023-09-27 18:17:44

假设你有一个属性和一个私有字段:

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

MessageBoxResult是一个枚举,用于获取消息框(WPF)的结果。尽管如此,当将MyResult传递给方法时,我遇到了问题,因为它自动使用枚举的值类型,并且改变的结果正在由GC收集,因为它现在是一个全新的变量,在我的方法(TaskBasedShow)的范围内指定…

我的当前设置:

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;

我确实读过以下文件:

  • https://msdn.microsoft.com/en-us/library/sbbt4032.aspx
  • https://msdn.microsoft.com/en-us/library/cc138362.aspx

,但似乎enum不提供Set(value)方法。


问题:

当设置枚举属性的变量时(在方法中),setter不会被触发,因此我的自定义事件也不会被触发。

它应该做什么:

在设置属性时应该触发OnRes,因为我的setter被触发,因此我的OnResult事件的订阅者被触发。工作的例子:

public MainWindow()
{
    InitializeComponent();
    OnRes += MessageBox_OnRes;
    MyResult = MessageBoxResult.Cancel;
}

它将打开另一个消息框,显示"Cancel"

注意:

一个解决方案是使用TaskBasedShow内部的属性:

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

,因为它现在使用引用类型,而不是传递的值类型。

如何在作为参数传递时触发枚举属性的setter

您应该使用回调来获取结果值

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 );
}

并将其命名为

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