gpt4 book ai didi

c# - ReactiveUI:从自定义对话框返回值

转载 作者:太空狗 更新时间:2023-10-30 01:30:06 25 4
gpt4 key购买 nike

我有一个窗口使用 ReactiveUI Interaction 打开第二个窗口作为模态对话框,然后从第二个窗口中的 ListBox 返回数据。

问题是当 .ShowDialog() 完成时,ViewModel 的 SelectedItem 的计算结果总是为 null。我已经确认绑定(bind)工作正常,并且所选项目在对话窗口的 ViewModel 中得到正确更新。只有当我返回交互时,该属性才重置为其默认值(空)。

我在这里整理了一个问题的最小示例:

https://github.com/replicaJunction/ReactiveDialogTest

主要测试逻辑在MainWindowViewModel.cs中。

编辑:这是代码中的一个基本思想片段:

GetNumberFromDialog = new Interaction<Unit, int>();
GetNumberFromDialog.RegisterHandler(interaction =>
{
var vm = new DialogWindowViewModel();

// Get a reference to the view for this VM
var view = Locator.Current.GetService<IViewFor<DialogWindowViewModel>>();

// Set its VM to our current reference
view.ViewModel = vm;

var window = view as Window;
var dialogResult = window.ShowDialog();

// At this point, vm.SelectedNumber is expected be the number the user selected -
// but instead, it always evaluates to 0.

if (true == dialogResult)
interaction.SetOutput(vm.SelectedNumber);
else
interaction.SetOutput(-1);
});

OpenDialog = ReactiveCommand.Create(() =>
{
GetNumberFromDialog.Handle(Unit.Default)
.Where(retVal => -1 != retVal) // If the dialog did not return true, don't update
.Subscribe(retVal =>
{
this.MyNumber = retVal;
});
});

重现问题的步骤:

  1. 运行项目。请注意带有 -5000 的标签 - 这是要更新的号码。
  2. 单击“打开对话框”按钮。一个对话窗口打开。
  3. 在列表框中选择一个数字。请注意,“当前选择”下的标签会更新 - 它绑定(bind)到与 ListBox.SelectedItem 相同的值。
  4. 点击确定。对话框关闭。

预期行为:主窗口中“我的号码是”下方的标签应更新为您在列表框中选择的值。

实际行为:标签更新为 0(整数的默认值)。

为什么我的 ViewModel 在对话框关闭时会自行重置?

最佳答案

查看您在 GitHub 上的示例有助于揭示问题。您的 DialogWindow 如下所示:

public partial class DialogWindow : Window, IViewFor<DialogWindowViewModel>
{
public DialogWindow()
{
InitializeComponent();
this.ViewModel = new DialogWindowViewModel();
this.DataContext = this.ViewModel;

this.ViewModel
.WhenAnyValue(x => x.DialogResult)
.Where(x => null != x)
.Subscribe(val =>
{
this.DialogResult = val;
this.Close();
});
}

public DialogWindowViewModel ViewModel { get; set; }
object IViewFor.ViewModel
{
get => ViewModel;
set => ViewModel = (DialogWindowViewModel)value;
}
}

在您的 MainWindowViewModel 中,您将 DialogWindow.ViewModel 属性设置为您的 DialogWindowViewModel实例。问题就出现在这个时候。您的问题是设置 DialogWindow.ViewModel 属性不会 设置 View 的 DataContext 或重新创建 WhenAnyValue可观察的。这意味着该 View 仍然绑定(bind)到 DialogWindowViewModel实例(在 DialogWindow构造函数)。要修复上面的示例代码,您可以简单地避免设置 ViewModel 属性,并使用已在对话框中设置的 ViewModel:

GetNumberFromDialog.RegisterHandler(interaction =>
{
// Get a reference to the view for this VM
var view = Locator.Current.GetService<IViewFor<DialogWindowViewModel>>();

var window = view as Window;
var dialogResult = window.ShowDialog();

// use the ViewModel here that's already set on the DialogWindow
if (true == dialogResult)
interaction.SetOutput(view.ViewModel.SelectedNumber);
else
interaction.SetOutput(-1);
});

关于c# - ReactiveUI:从自定义对话框返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47680814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com