I have been having this issue and have been trying to figure out for the past few days, I set up a second test project as my first project is too big to try and nail this down. I'm still fairly new to mvvm so I'm still learning. Whenever I try to save a field using Entity it starts complaining the FirstName field is required, I sort of nailed down the issue to being apart of something with the button because whenever I move the button into the same UserControl as the textbox it will save. The TabControl in the MainWindow has a UserControl for each tab and each one has their own respective ViewModel and then the TabControl itself has a ViewModel.
MainWindow Just contains the button and the tab control
<Window.Resources>
<vm:TabControlViewModel x:Key="tab"/>
</Window.Resources>
<Grid DataContext="{StaticResource tab}">
<TabControl Margin="10"
Width="500"
Height="500">
<TabItem Header="Test Tab 1">
<custom:TabOneUserControl/>
</TabItem>
<TabItem Header="Test Tab 2">
<custom:TabTwoUserControl/>
</TabItem>
</TabControl>
<Button Content="Save"
Width="120"
Height="50"
Margin="1114,604,41,38.5"
Command="{Binding SaveCommand}"/>
</Grid>
TabOneUserControl Contains a textbox and label
<UserControl.Resources>
<vm:TabOneUserControlViewModel x:Key="vm"/>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
<StackPanel VerticalAlignment="Center">
<Label Content="First Name"
HorizontalAlignment="Center"/>
<TextBox Width="250"
Height="50"
Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
</UserControl>
TabTwoUserControl Contains a textbox and label
<UserControl.Resources>
<vm:TabTwoUserControlViewModel x:Key="vm"/>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
<StackPanel VerticalAlignment="Center">
<Label Content="Last Name"
HorizontalAlignment="Center"/>
<TextBox Width="250"
Height="50"
Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
</UserControl>
TabControlViewModel For the tab control
public class TabControlViewModel
{
public SaveCommand SaveCommand { get; set; }
private TabOneUserControlViewModel tabOneUserControl;
private TabTwoUserControlViewModel tabTwoUserControl;
public TabControlViewModel()
{
tabOneUserControl = new TabOneUserControlViewModel();
tabTwoUserControl = new TabTwoUserControlViewModel();
SaveCommand = new SaveCommand(this);
}
public void SaveInformation()
{
using (TestDbEntities test = new TestDbEntities())
{
test.FNs.Add(new FN
{
FirstName = tabOneUserControl.FirstName
});
test.LNs.Add(new LN
{
LastName = tabTwoUserControl.LastName
});
try
{
test.SaveChanges();
Debug.Print("SAVED CHANGES!");
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation(
"Class: {0}, Property: {1}, Error: {2}",
validationErrors.Entry.Entity.GetType().FullName,
validationError.PropertyName,
validationError.ErrorMessage);
}
}
}
}
}
}
TabOneUserControlViewModel For the first tab user control
public class TabOneUserControlViewModel : INotifyPropertyChanged
{
private string firstName;
public event PropertyChangedEventHandler PropertyChanged;
public string FirstName
{
get { return firstName; }
set
{
firstName = value;
OnPropertyChanged("FirstName");
}
}
public TabOneUserControlViewModel()
{
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
TabTwoUserControlViewModel For the second tab user control
public class TabTwoUserControlViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string lastName;
public string LastName
{
get { return lastName; }
set
{
lastName = value;
OnPropertyChanged("LastName");
}
}
public TabTwoUserControlViewModel()
{
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
Thanks to everyone in the comments for your suggestions, Nawed's comment nailed it perfectly for what I was doing wrong. Here is the final code changes I made:
TabControlViewModel Removed the fields and made them into properties
public class TabControlViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public SaveCommand SaveCommand { get; set; }
public TabOneUserControlViewModel TabOneUserControl { get; set; }
public TabTwoUserControlViewModel TabTwoUserControl { get; set; }
public TabControlViewModel()
{
TabOneUserControl = new TabOneUserControlViewModel();
TabTwoUserControl = new TabTwoUserControlViewModel();
SaveCommand = new SaveCommand(this);
}
public void SaveInformation()
{
using (TestDbEntities test = new TestDbEntities())
{
test.FNs.Add(new FN
{
FirstName = TabOneUserControl.FirstName
});
test.LNs.Add(new LN
{
LastName = TabTwoUserControl.LastName
});
try
{
test.SaveChanges();
Debug.Print("SAVED CHANGES!");
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation(
"Class: {0}, Property: {1}, Error: {2}",
validationErrors.Entry.Entity.GetType().FullName,
validationError.PropertyName,
validationError.ErrorMessage);
}
}
}
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
TabOneUserControl Removed the static resource from the grid and replaced it with a regular binding and then changed the binding in the Text element, this was the same thing I did in the second user control so I will negate posting the second UserControl:
<Grid DataContext="{Binding TabOneUserControl}">
<StackPanel VerticalAlignment="Center">
<Label Content="First Name"
HorizontalAlignment="Center"/>
<TextBox Width="250"
Height="50"
Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
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.