I am having a binding issue I wasn't able to figure out for the past two days. I have thoroughly went through most of the relevant threads on SO, and I still wasn't able to pinpoint where my error lies.
The issue I'm having is with one of the textboxes in my program. The purpose of it is to show the file the user has selected from the file browser. I have bound the text property of it to a string called parameterFileSelected but the textbox never updates even though debugging seems to be showing that the iNotifyPropertyChanged is called and executed properly.
Please help me take a look at my code below if there are any mistakes in my code.
The textbox is part of an xaml called GenerateReports and this view is tied to the GenerateReportsViewModel as follows:
Code for setting datacontext to GenerateReportsViewModel
<Grid > <Grid.DataContext> <vm:GenerateReportsViewModel/> </Grid.DataContext> <Grid.ColumnDefinitions> .... Code for TextBox. I have tried removing the Twoway mode, changing it to Oneway and removing the mode but there is no difference.
<TextBox Grid.Column="2" Grid.Row="1" Margin="5" Text="{Binding parameterFileSelected, Mode=Twoway, UpdateSourceTrigger=PropertyChanged}" ></TextBox> To get the file browser and then to pass the selected file result to the GenerateReportsViewModel, this is the function in the codebehind file. The genviewmodel is initialized in the beginning of the codebehind file as GenerateReportsViewModel genViewModel = new GenerateReportsViewModel();
private void ParaFileButtonClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); if (openFileDialog.ShowDialog() == true) { DataContext = genViewModel; genViewModel.updateParameterFileSelected(openFileDialog.FileName.ToString()); } } This is the code that's called in GenerateReportsViewModel to update the parameterFileSelected string the textbox is bound to.
class GenerateReportsViewModel : ViewModelBase { private string _parameterFileSelected; public string parameterFileSelected { get { return _parameterFileSelected; } set { SetValue(ref _parameterFileSelected, value); } } public void updateParameterFileSelected(string parameterFile) { parameterFileSelected = parameterFile; } } Here is the ViewModelBase the viewmodel is attached to.
public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void SetValue<T>(ref T property, T value, [CallerMemberName] string propertyName = null) { if (property != null) { if (property.Equals(value)) return; } OnPropertyChanged(propertyName); property = value; } protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } } EDIT Working Solution after Applying Kevin's Suggestions
For simplicity sake, the Datacontext was set in the XAML.
<Grid> <Grid.DataContext> <vm:GenerateReportsViewModel x:Name="generateReportsViewModel"/> </Grid.DataContext> Then, I call the string the textbox was bound to, in the viewmodel directly from code behind.
private void ParaFileButtonClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); if (openFileDialog.ShowDialog() == true) { generateReportsViewModel.parameterFileSelected = openFileDialog.FileName.ToString(); } } The ViewModel now uses Kevin's ViewModelBase:
public class GenerateReportsViewModel : ViewModelBase { public string parameterFileSelected { get { return this.GetValue<string>(); } set { this.SetValue(value); } } } Thank you Kevin for your solution. Now my 2-day-long problem is solved.
I found out that my previous ViewModelBase was calling iNotifyPropertyChanged but somehow when the View was updated, the value was null instead.