2
votes

Using Mvvm library, UWP, C#.

Problem: View won't update content of a textbox if value is changed in the viewmodel and the textbox has focus on that moment. It is possible to update a viewmodel property of a textbox that hasn't got the focus.

To clear confusion: Textbox -> Has focus -> Something is typed -> Is passed to bound property -> Property set, changes value and calls RaisePropertyChange. -> Textbox does not update.

If the property that is bound to a different TextBox is changed in the ViewModel, and RaisePropertyChanged is called with that property as target, that TextBox does get updated.

The difference seems to be that the Textbox that has focus doesn't update on RaisePropertyChanged. It does do this in wpf.

Code below is an example, not the actual application. It does show the problem, and acts just like the actual application. Hyphen is added to change the input. If RaisePropertyChanged did work, the hyphen would show up in the editbox, it doesn't.

My page:

<Page x:Class="BindingTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BindingTest.VML"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding MainViewModel, Source={StaticResource Locator}}" >

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="0,144,0,109">
    <TextBox x:Name="textBox1" 
             Text="{Binding Item1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             HorizontalAlignment="Left" 
             Margin="10,137,0,0" 
             TextWrapping="Wrap" 
             VerticalAlignment="Top" 
             Width="340"/>

    <TextBox x:Name="textBox2" 
             Text="{Binding Item2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             HorizontalAlignment="Left" 
             Margin="10,174,0,0" 
             TextWrapping="Wrap"
             VerticalAlignment="Top" 
             Width="340"/>
</Grid>

My ViewModel:

using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;

namespace BindingTest
{
    public class MainViewModel:ViewModelBase
    {        
        string _item1 = "";
        string _item2 = "";

        public string Item1 {
            get
            {
                return _item1;
            }
            set
            {
                _item1 = value + "-";
                RaisePropertyChanged("Item1");                               
            }
        }

        public string Item2
        {
            get {
                return _item2;
            }
            set
            {
                _item2 = value + "-";
                RaisePropertyChanged("Item2");
            }
        }
    }
}

If text is put into either one of the textboxes, the set of the properties is called, value is changed, value isn't updated in the textbox.

If I would call the propertychanged of textbox2 in the setter of textbox1, it will update:

        public string Item1 {
            get
            {
                return _item1;
            }
            set
            {
                _item2 = value + "-";
                RaisePropertyChanged("Item2");                               
            }
        }

It is as if the textbox that has the focus won't update it's content as long as it has the focus.

2
Too many pronouns lacking unambiguous antecedents! I don't understand your problem description. Please be more precise, so that it's completely clear what user action(s) are performed, what exactly happens, and what you expected instead. I can't tell from your post whether you are having trouble with the view not being updated when the view model is changed somehow or with the view model not being updated when the view is changed somehow, or something else. It's also not clear why a) you are modifying the input by adding a hyphen, and b) why you'd set _item2 in the Item1 setter. - Peter Duniho
I would think this behavior is intentional, it would be annoying if you are typing in a textbox and all of a sudden its value changes mid-typing when the viewmodel property changes. - Decade Moon
@PeterDuniho After problem, it says: View won't update content of a textbox if value is changed in the viewmodel and the textbox has focus on that moment. If in the viewmodel the value that is bound is changed, and a raisepropertychanged is called, the value in the textbox won't update. - Bolke

2 Answers

0
votes

Try removing

updateSourceTrigger=PropertyChanged

from your textbox binding

RaisePropertyChanged on the viewmodel should be enough

0
votes

Here is trick I use:

Instead of calling RaisePropertyChanged() call the following method :

    public async void ForceRaisePropertyChanged(string propName)
    {
        await Task.Delay(1);
        RaisePropertyChanged(propName);
    }

It works like a charm.