I’m learning MVVM pattern and I have a simple issue.
I have created a class whose properties I want to bind into text boxes inside a Dialog (in this case I only have one property):
public class NewObjectClass : ObservableObject
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
}
This is the ViewModel of the Dialog:
class ObjCreationViewModel : ObservableObject
{
// Class whose properties I want to bind in text boxes
private NewObjectClass _newObject;
public NewObjectClass NewObject
{
get { return _newObject; }
set { _newObject = value;
OnPropertyChanged("NewObject");
}
}
// String to test binding
private string _test;
public string Test
{
get { return _test; }
set { _test = value; }
}
// Create new object view
private DelegateCommand _createNewObject;
public DelegateCommand CreateNewObjectCmd => _createNewObject ?? (_createNewObject = new DelegateCommand(CreateNewObject));
void CreateNewObject()
{
// Do things in the future
}
public ObjCreationViewModel()
{
// Instance of New Object
NewObjectClass NewObject = new NewObjectClass();
// New object property that I want to show in TextBox
NewObject.Name = "Why this one is not working?";
// String text that works
Test = "Why this is working?";
}
}
And finally this is the view:
<UserControl x:Class="AOE.MVVM.View.ObjCreationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AOE.MVVM.View"
xmlns:viewmodel="clr-namespace:AOE.MVVM.ViewModel"
mc:Ignorable="d"
MinHeight="500" MinWidth="500">
<UserControl.DataContext>
<viewmodel:ObjCreationViewModel/>
</UserControl.DataContext>
<Border Grid.ColumnSpan="4" CornerRadius="20"
Background="White" BorderBrush="Black" BorderThickness="1.5">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1">
<StackPanel Orientation="Horizontal">
<Label Margin="10" Content="Object name:" Style="{StaticResource DescriptionLabelStyle}"/>
<TextBox x:Name="TextObjectName" Width="200" Height="25" Text="{Binding NewObject.Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</StackPanel>
</StackPanel>
<Button Grid.Row="1" Margin="5" Name="CreateBtn" Width="75" Height="30" Content="Create" FontFamily="Verdana" Foreground="#007BC0" FontWeight="Bold" Background="Transparent" BorderThickness="3" BorderBrush="#007BC0" VerticalAlignment="Bottom" Command="{Binding CreateNewObjectCmd}"/>
</Grid>
</Border>
The issue is that I can’t bind the property Name of "NewObject" into the text box, however if I bind "Test", It works properly.
I want to show in the textbox the property value and also if I change the value in the textbox, change the property value of the instance "NewObject".
Anybody could tell me what is wrong?
PD "ObservableObject class that implements PropertyChange event":
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyname = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
>Solution :
The line
NewObjectClass NewObject = new NewObjectClass();
defines a local variable NewObject, but does not set the property NewObject.
Change it to
NewObject = new NewObjectClass();