1

Question at the end

Information : I use Modern UI but I think that this problem might not be related only to this framework, hence I posted it under 'wpf' and 'data-binding'.

What am I trying to accomplish:

I have datagrid with some simple data in it (let's call this data products). I want to create a following feature. After double click on row user is being redirected to a 'product edition' page (let's call this page ProductPage.xaml) where there will be more information about product. Before showing all data to user application is supposted to call SQL Server and ask for all info about selected product. Later on user can see all info about product where he can edit it. User accepts editions by clicking on the button, if button wasn't clicked but if he go to other page without clicking this button edits should be disregarded.

Problem

After a redirection to ProductPage.xaml with basic info about product hidden in Application.Current.Properties this page is not being refreshed. Constructor is not being called (as I suspect this is expected behavior) hence I created method which is being called after page is loaded however even if model is being refreshed page is not. All bindings do work correctly during first page load (when constructor is being called) but when I go back to datagrid and choose different row old model is present.

Code How do I make a redirect? Firstly what I did was :

 public void MouseDoubleClickMethod()
{
/// getting id by row Id = ...
 var url = $"ProductPage.xaml?id={id}"
 BBCodeBlock bs = new BBCodeBlock();
 Application.Current.Properties["product_id"] = Id;
 bs.LinkNavigator.Navigate(new Uri(url, UriKind.Relative), this);
///some code
}

My model simplified

public class Product : INotifyPropertyChanged{
private decimal _price;
public decimal Price
    {
        get { return _price; }
        set
        {
            _price = value;
            OnPropertyChanged(nameof(Price));

        }
    }
public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

My binding simplified (Product is a public property)

<StackPanel DataContext="{Binding RelativeSource={RelativeSource AncestorType=Page}}"> 
<StackPanel DataContext="{Binding Path=Product}">
<TextBox x:Name="Price" Text="{Binding Path=Price, Mode=TwoWay}" />

My after-load method simplified

productId = (int)Application.Current.Properties["product_id"];
Product.UpdateFrom(Database.GetGetProduct(id)); // this method updates all fields in model

Comments

Model DOES change but it it is textbox not refreshing. Textbox keeps the same data regardless being binded to a property. I use ?id={id} to make sure that other row is being loaded, without it it keeps showing first double clicked row's data.

I suspect my bindings to be faulty.

Question

What can I do with this binding? I want my textbox to refresh after page load not only when new object is being constructed. If you have no idea what to do with it just post some suggestions on how to debug it.

This is fixable by using GUID as parameter in url but I do not want to do that. Why? It forces to execute page constructor (hence rebuilding xaml).

MaLiN2223
  • 1,290
  • 3
  • 19
  • 40

1 Answers1

1

If I recall correctly, MUI, when using it's navigation framework, it caches the data for the page. It doesn't construct the view (and subsequently your view model) each time it navigates. To support this, MUI has added navigation events for you to hook into to be notified when views are navigated to/from. in these events you could then update your data. From their wiki

Make your content navigation aware by implementing the IContent interface available in the FirstFloor.ModernUI.Windows namespace.

You can have your view model implement the interface and on load, refresh your data.

xtreampb
  • 528
  • 6
  • 19