I've got the following class:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ImportDefinitieGenerator.LinkTypeDetail.Detail
{
abstract class LinkTypeDetailBase : INotifyPropertyChanged
{
public string Property { get; set; }
private string _Value;
public event PropertyChangedEventHandler PropertyChanged;
public string Value { get { return _Value; }
set
{
_Value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
}
}
public LinkTypeDetailBase(string Property)
{
this.Property = Property;
this.Value = "";
}
internal abstract void Click();
}
}
Nice and simple. This class works fine, when Value
gets changed the PropertyChanged
fires. But now I'm trying to set the Value
from a dialog, so I use:
Value = await StringDialog.getString(Property, Value);
which in turn calls
public async static Task<string> getString(string title, string defaultText = "")
{
StringDialog stringDialog = new StringDialog(title, defaultText);
await stringDialog.ShowAsync();
return stringDialog.TextBox.Text;
}
Now my problem arises. Everything works fine and dandy, apart from that the PropertyChanged
event gets fired the moment the StringDialog
shows up, not after the await and return. As a result, the value has not yet been changed at the moment it fires.
Is this intended behavior? If so, what would be the correct way of handling this? And if not, how would I work around this properly? (I'm sure I could hack my way around it, so I'm specifically asking about how to do it properly.)
Edit:
Okay, after trying to create a Minimal, Complete and Verifyable example, it seems that I'm in the wrong here. I'll attach the code for future reference. The bug is not where I expected it to be, and as such this has become a hunt for a bug in my code turning this question off-topic. When I find the cause, I will post it would it be useful for future reference.
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace MCV
{
sealed partial class App : Application
{
private static VerifyMyBug verifyMyBug;
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
Window.Current.Activate();
}
verifyMyBug = new VerifyMyBug();
verifyMyBug.PropertyChanged += (o, e1) =>
{
throw new NotImplementedException("Property changed");
};
verifyMyBug.DelayedSet();
}
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
deferral.Complete();
}
}
class VerifyMyBug : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _Value;
public string Value
{
get { return _Value; }
set
{
_Value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value"));
}
}
public async void DelayedSet()
{
Value = await GetStringDelayed();
throw new NotImplementedException("Done setting variable");
}
public async Task<string> GetStringDelayed()
{
await Task.Delay(TimeSpan.FromSeconds(5));
return "Hello";
}
}
}
Edit 2: Okay, the event did fire, it just got lost somewhere along the way. My apologies for wasting your time.