Disclaimer I feel like this is a fairly simple question, so i must reiterate that I did look for an answer and couldn’t find anything!
Not sure if I am asking the question correctly, but I will tell you this. I am working on becoming more familiar with MVVM, so I am messing around with a ridiculously simple project of two stackpanels, ten textboxes, and some simple binding. Everything works now, since I have two panels, which separates my boxes and lets me set two datacontext.
My question is this:
a) is it possible to set the datacontext on a parent element (Stackpanel) and have half of my child elements (textboxes) use that context via inheritance and then give the other half of the elements A DIFFERENT data context?
and
b) if this is possible, how??
Thanks people-smarter-than-I
Here is the code that is trying so hard, but not really doing anything I want it to be doing:
XAML
<Grid>
<StackPanel>
<StackPanel HorizontalAlignment="Left" Margin="8,8,0,75" Width="224" DataContext="{Binding Path=Customer}">
<TextBox Text="{Binding Path=FirstName}" Height="28" Name="label1"/>
<TextBox Text="{Binding Path=MiddleName}" Height="28" Name="l2"/>
<TextBox Text="{Binding Path=LastName}" Height="28" Name="l3"/>
<TextBox Text="{Binding Path=CompanyName}" Height="28" Name="l4"/>
<TextBox Text="{Binding Path=EmailAddress}" Height="28" Name="l5"/>
<!--I want the next five TextBox elements to bind to a different datacontext-->
<TextBox Text="{Binding Path=FirstName}" Height="28" Name="label11"/>
<TextBox Text="{Binding Path=MiddleName}" Height="28" Name="l21"/>
<TextBox Text="{Binding Path=LastName}" Height="28" Name="l1lgh3"/>
<TextBox Text="{Binding Path=CompanyName}" Height="28" Name="l1hj4"/>
<TextBox Text="{Binding Path=EmailAddress}" Height="28"/>
</StackPanel>
</StackPanel>
</Grid>
Code Behind C#
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new MainViewModel();
}
}
View Model
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
PopulateCustomerInfo();
}
private Customer customer;
public Customer Customer
{
get { return customer; }
set
{
customer = value;
OnPropertyChanged("Customer");
}
}
private Customer customer2;
public Customer Customer2
{
get { return customer2; }
set
{
customer2 = value;
OnPropertyChanged("Customer");
}
}
private void PopulateCustomerInfo()
{
AdventureWorksLTE ctx = new AdventureWorksLTE();
this.Customer = (from c in ctx.Customers
select c).FirstOrDefault();
this.Customer2 = (from c in ctx.Customers
orderby c.FirstName descending
select c).FirstOrDefault();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handle = PropertyChanged;
if (handle != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handle(this, e);
}
}
}
Well, you can do various things like changing the
DataContextlocally on all those lowerTextBoxes:The question really is though: What do you want to achieve? Does it make sense to even set the DataContext on the StackPanel?
Maybe you should not and use a longer path instead:
It all depends on what properties are going to be used in the child controls, if most or all of them are in
Customer, sure, set it to keep the bindings short. If you need the main view model in some places you can useRelativeSourceto get to a control with the right data context and change the path accordingly. (DataContext.*, data context appears in the path as a different source is specified)