0

I have an usercontrol in a UWP who I place in other user controls who have two text TextBlocks who are bound to the VM.

Here is the XAML Code:

DataContext

DataContext="{Binding BalanceView, Source={StaticResource CoreModule}}"


<TextBlock Text="{Binding TotalBalance, Mode=TwoWay, Converter={StaticResource AmountFormatConverter}, UpdateSourceTrigger=PropertyChanged}"
           Style="{StaticResource DeemphasizedBodyTextBlockStyle}"
           Margin="0,0,5,0" />
<TextBlock Text=" / "
           Style="{StaticResource DeemphasizedBodyTextBlockStyle}"
           Margin="0,0,5,0" />
<TextBlock Text="{Binding EndOfMonthBalance, Mode=TwoWay, Converter={StaticResource AmountFormatConverter}, UpdateSourceTrigger=PropertyChanged}"
           Style="{StaticResource DeemphasizedBodyTextBlockStyle}"
           Margin="0,0,5,0" />

And the VM Properties there bound to:

public double TotalBalance
{
    get { return totalBalance; }
    set
    {
        if (Math.Abs(totalBalance - value) < 0.01) return;

        totalBalance = value;
        RaisePropertyChanged();
    }
}

public double EndOfMonthBalance
{
    get { return endOfMonthBalance; }
    set
    {
        if (Math.Abs(endOfMonthBalance - value) < 0.01) return;

        endOfMonthBalance = value;
        RaisePropertyChanged();
    }
}

public event PropertyChangedEventHandler PropertyChanged;

/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null)
    {
        var e = new PropertyChangedEventArgs(propertyName);
        handler(this, e);
    }
}

I can see that the value returned is correct. But on the UI it's permanently on 0. If I set the value staticly to a value it's shown properly.

What is wrong?

Szabolcs Dézsi
  • 8,743
  • 21
  • 29
NPadrutt
  • 3,619
  • 5
  • 24
  • 60
  • 1
    I assume there is a binding error. If you set the setting found here to All, do you see binding errors in the Debug/Output window? http://stackoverflow.com/a/8850185/4620101 – Szabolcs Dézsi Jan 10 '16 at 15:09
  • Check your converters and set a breakpoint to see if you catch something when RaisePropertyChanged is called. Also, how did you set your DataContext? –  Jan 10 '16 at 15:10
  • Unfortunately there are no binding errors logged even when I set the setting to all. Also the issue still occurs when I remove the converter – NPadrutt Jan 10 '16 at 15:16
  • I added a own INotifyPropertyChanged Implementation and override the one of the VM. But the handler is always null. That might be the reason. But I can't find out why this is the case. – NPadrutt Jan 10 '16 at 15:37
  • Strange.. I moved the declaration of the DataContext to the constructor and now it works as before... – NPadrutt Jan 10 '16 at 15:46
  • Minor point: There's no need to `TwoWay` bind a `TextBlock` because the user can't edit it. – Peter Torr - MSFT Jan 10 '16 at 16:31
  • Oh, yeah. Absolutly. I put them for test purposes. =) – NPadrutt Jan 10 '16 at 16:33
  • @NPadrutt what does `RaisePropertyChanged` do and how it is different to `OnPropertyChanged`? – dkozl Jan 10 '16 at 16:43
  • RaisePropertyChanged is defined in the MVX lib. In order to debug I created an own implementation. – NPadrutt Jan 10 '16 at 16:47

2 Answers2

0

I would suspect you have these double values as private properties which are not shown here, but are referenced such as "totalBalance" vs PUBLIC "TotalBalance" and similar with "endOfMonthBalance" vs "EndOfMonthBalance", otherwise it would not compile.

Also, shouldn't your RaisePropertyChanged() call RaisePropertyChanged("TotalBalance") and RaisePropertyChanged("EndOfMonthBalance") vs a blanket call via no parameter.

DRapp
  • 47,638
  • 12
  • 72
  • 142
  • True. But the issue seems to be that there is no subscription for changes when I set de Data Context in XAML only when i set it in the constructor. RaisePropertyChanged uses CallerMemberName I assume. This way it will automaticly get the name of the of the caller and you don't need to set it manually. – NPadrutt Jan 10 '16 at 16:46
  • @NPadrutt, Have you tried adding "NotifyTargetOnUpdate=True", "NotifySourceOnUpdate=True" to the bindings as a TEST? I have seen a variety of strangeness as I still don't fully understand how things work under the hood in some areas. – DRapp Jan 10 '16 at 16:55
  • Belongs that to the data context property or where do I have to set that? – NPadrutt Jan 10 '16 at 17:01
  • @NPadrutt, within existing... I have taken a snippet. As you type, it will auto-help XAML for you... Text="{Binding TotalBalance, Mode=TwoWay, NotifySourceOnUpdate=True, NotifyTargetOnUpdate=True, Converter... etc – DRapp Jan 10 '16 at 17:03
  • I checked this, but both attributes seems to be not available in uwp. – NPadrutt Jan 14 '16 at 23:07
0

Call OnPropertyChanged passing the name of the CLR property as the paramter.

private double totalBalance=0;   
public double TotalBalance
{
    get { return totalBalance; }
    set
    {
        if (Math.Abs(totalBalance - value) < 0.01) return;

        totalBalance = value;
        OnPropertyChanged("TotalBalance");
    }
}

private double endOfMonthBalance=0;
public double EndOfMonthBalance
{
    get { return endOfMonthBalance; }
    set
    {
        if (Math.Abs(endOfMonthBalance - value) < 0.01) return;

        endOfMonthBalance = value;
        OnPropertyChanged("EndOfMonthBalance");
    }
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}
Subru
  • 343
  • 2
  • 13
  • This is already done with the [CallerMemberName] Attribute in the RaisPropertyChanged. Since it's in the BaseViewModel of the lib I couldn't post it here. But when I add the propertie it says it's obsolet. – NPadrutt Jan 14 '16 at 23:06