简体   繁体   中英

Why dynamically changed data not updated on MVVM binding here

I am using Mvvm approach in silverlight. where i try to bind a TextBox like this :

<Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding ViewModelText}" Grid.Row="0"></TextBlock>       
</Grid>

where this xaml.cs class behind this xaml is:

 public partial class UIeLementRender : UserControl
    {
        public UIeLementRender()
        {
            InitializeComponent();
            this.DataContext = new ViewModel.TabControlStuffViewModel.uiElementRendererViewModel();
        }
    }

and viewmodel class is:

public class uiElementRendererViewModel: GenericViewModel 
{

    private String viewModelText;
    public String ViewModelText 
    {
        get 
        {
            return viewModelText;
        }
        set 
        {
            viewModelText = value;
            OnPropertyChanged("ViewModelText");
        }
    }
    public uiElementRendererViewModel() 
    {
        this.viewModelText = "Hii from UIelemnt  rendering"; //this updated but below one is never updated.
    }

    public uiElementRendererViewModel(ProgramVersion pv) //This constructor is called dynamically on abutton click from other view model class but it never updates the viewModelText
    {      
        this.viewModelText = "Hii changed  UIelemnt  rendering";
        this.OnPropertyChanged("ViewModelText");
    }
}

Now when i run the code it shows me "Hii from UIelemnt rendering"; (which is correct) but when i press a button from another viewmodel class dynamically, i wan to update the new text on viewModelText to "Hii changed UIelemnt rendering" . Which is not updated even i have done "this.OnPropertyChanged("ViewModelText");" in my second costructor. (it is still has the text of default constructor/without parameter)

How to update this nex text which is obtained dynamically ?

You need to set the actual property, not re-initialize the whole ViewModel:

viewModel.ViewModelText = "Hii changed  UIelemnt  rendering";

The call to OnPropertyChanged in your constructor is redundant, as that will run before any actual binding happens.

If you -have- to re-initialize the ViewModel, and there's no possible way around this, then you also need to re-initialize the view, or manually set the DataContext of the existing view to the new instance of the ViewModel class.

I've created a few sample files that illustrate how it -could- be done: http://pastebin.com/W6Yh7N6E

I'll try to illustrate how WPF would do the databinding with a short list here:

  1. Create View
  2. Create ViewModel (Instantiate, run constructor, etc.) - This is where the event is currently fired in your own example
  3. Set ViewModel as DataContext (Which in your example never happens anyways)
  4. WPF Updates its bindings with current values (So no need for another PropertyChanged event here)

There's a bunch more stuff happening behind the scenes, but these steps should be sufficient to give you a decent understanding of why the PropertyChanged event wouldn't do anything in a constructor.

When you create a new viewmodel from you button click, you actually have two instances of the viewmodel. The UI however is still bound to the first one, so whatever changes you make in the second, will never appear on the UI. You could set the second instance as new DataContext:

private void OnButtonClick(object sender, EventArgs e)
{
    this.DataContext = new ViewModel.TabControlStuffViewModel.uiElementRendererViewModel(/*pass variable here*/);
}

But this is hardly what you actually want. What you should do instead is modify the existing viewmodel object:

private void OnButtonClick(object sender, EventArgs e)
{
   var vm = this.DataContext as uiElementRendererViewModel; // Get the current view model and cast it to correct type
   vm.ViewModelText = "Enter new text here"; // Update the text
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM