Search code examples
c#wpfprismshowdialog

How to retrieve int value from DialogService.ShowDialog() and assign that value to the view where ShowDialog function is called?


My dialogView consist of listbox whose itemsource is bound to an ObservableCollection class of Linq-to-SQL database table and 2 buttons - Accept which will accept the selected item from listbox and Close button to close dialog window. I have bound an int? variable to SelectedIndex of listbox which will help to retrieve value from ObservableCollection class.

DialogViewModel.cs

private static AssignDatabaseDataContext _adpDC = new AssignDatabaseDataContext();
private readonly ObservableRateList rateList;

public int SelectedRateItemIndex { get; set; }
public int? RateSelected { get; set; }

private int? selectedratevalue;
public int? SelectedRateValue 
{
    get 
    {
        selectedratevalue = rateList[3].RateValue;
        return selectedratevalue; 
    }
    set => this.SetProperty(ref this.selectedratevalue, value);
}

public int RateValueSelect
{
    get { return SelectedRateValue == null ? Convert.ToInt32((string)null) : Convert.ToInt32(rateList[SelectedRateItemIndex].RateValue); }
}

public string Title => "";

public ObservableCollection<RateTable> rateTables { get; set; }

public DelegateCommand CloseCommand { get; set; }
public DelegateCommand AcceptCommand { get; set; }

public event Action<IDialogResult> RequestClose;

public RateSelectViewModel()
{
    this.rateList = new ObservableRateList(_adpDC);
    this.rateTables = rateList;//new ObservableCollection<RateTable>();

    this.CloseCommand = new DelegateCommand(this.CloseDialog);
    this.AcceptCommand = new DelegateCommand(this.AcceptRateResult);
}

public bool CanCloseDialog()
{
    return true;
}

private void CloseDialog()
{
    this.RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
}

public void OnDialogClosed()
{
    //throw new NotImplementedException();
    this.RaisePropertyChanged(nameof(RateSelected));
}

public void OnDialogOpened(IDialogParameters parameters)
{
    this.RateSelected = parameters.GetValue<int>(DialogNames.RateSelected);
    this.rateTables = parameters.GetValue<ObservableRateList>(DialogNames.RateDialogList);
    this.RaisePropertyChanged(nameof(RateSelected));

    //this.AcceptRateResult();
}

private void AcceptRateResult()
{
    RateSelected = this.rateList[SelectedRateItemIndex].RateValue.Value;

    if (this.RateSelected == null && this.RateSelected == rateList[3].RateValue)
    {
        return;
    }

    // OnPropertyChanged();
    this.RaisePropertyChanged(nameof(RateSelected));
    this.RequestClose?.Invoke(new DialogResult(ButtonResult.OK));
}

I'm expecting DialogService.showDialog to return index value or item value from dialog Window so the value can be assigned to label of MainView from where the function is being called. I have passed the DialogName and parameters which will help me to retrieve the value but it doesn't work as it should.

MainViewModel.cs

protected IDialogService dialogService;

public event Action<IDialogResult> RequestClose;

private int? rateselected;

public int? RateSelected
{
    get
    {
        rateselected = rateList[30].RateValue;
        return rateselected;
    }
    set => this.SetProperty(ref this.rateselected, value);
}

public int? PulseWidthSelected
{
    get 
    {
        var pulsewidth = pulsewidthList[4].PulseWidthValues;
        return pulsewidth;
    }
}

private static AssignDatabaseDataContext _adpDC = new AssignDatabaseDataContext();
private  ObservableRateList rateList;
private readonly ObservablePulseWidthList pulsewidthList;

private readonly ObservableCollection<RateTable> rateTables;
private readonly ObservableCollection<PulseWidthTable> pulseWidthTables;

public ICommand PulseWidthDialogCommand { get; set; }
public ICommand RateDialogCommand { get; set; }

public PulseWidthRateViewModel(IDialogService dialogservice)
{
    rateList = new ObservableRateList(_adpDC);
    pulsewidthList = new ObservablePulseWidthList(_adpDC);
    this.RaisePropertyChanged(nameof(RateSelected));
    this.dialogService = dialogservice;
            
    //Convert.ToInt32(this.rateTables.Where(i => i.RateValue == 50));
    this.PulseWidthDialogCommand = new DelegateCommand(this.ShowPulseWidthDialog);
    this.RateDialogCommand = new DelegateCommand(this.ShowRateDialog);
    this.pulseWidthTables = new ObservableCollection<PulseWidthTable>();
    this.rateTables = rateList;

    //Convert.ToInt32(rateTables.Select(s => s.RateValue == 50));//this.rateList[30];
}

private void ShowPulseWidthDialog()
{
    // var parameters = new DialogParameters { { } };
}

private void ShowRateDialog()
{
    if (RateSelected == null && RateSelected == rateList[30].RateValue)
    {
        return;
    }

    var currentValue = this.RateSelected ?? 0;

    this.RaisePropertyChanged(nameof(currentValue));

    var parameters = new DialogParameters {
                { DialogNames.RateSelected, currentValue },
                { DialogNames.RateDialogList, rateTables }
            };

    dialogService.ShowDialog(DialogNames.RateSelectDialog, parameters, null);
    //this.dialogService.ShowDialog(dia);
}

Solution

  • dialogService.ShowDialog(DialogNames.RateSelectDialog, parameters, null);

    ShowDialog does not return the result as return value, but rather passes it to your callback (the null).

    If provide an actual clallback, you'll receive the result from the dialog an can pass it on to the caller of ShowDialog, e.g. via closure.

    For example:

    // returning the result
    this.RequestClose?.Invoke(new DialogResult(ButtonResult.OK, new DialogParameters { { "selectedRateValue", selectedratevalue.Value } }));
    
    // receiving the result
    int selectedRateValue;
    dialogService.ShowDialog(DialogNames.RateSelectDialog, parameters, result => result.Parameters.TryGetValue( "selectedRateValue", out selectedRateValue) );