Reputation: 5394
A newbie binding question. I have multiple usercontrols called by my mainview.xaml, like:
<i:InkRichTextView RichText ="{Binding LastNote}" ... />
where RichText is a dependency property in the code-behind of the InkRichTextView.xaml user control and LastNote is a property of the mainviewmodel.
The MainViewModel is associated implicitly with the MainView by way of a DataTemplate in the App.xaml, like:
<DataTemplate DataType="{x:Type vm:MainViewModel}">
<v:MainView/>
</DataTemplate>
I would like to set the usercontrol InkRichTextView to its own ViewModel, the property of which is being held in the MainViewModel, something like:
<i:InkRichTextView RichText ="{Binding LastNote}" DataContext="{Binding ucFirstControl}" ... />
but when I do so, my user control InkRichTextView loses the context for LastNote (or looses access to its dependency property in its code-behind, or both??).
How can I maintain the binding to the MainViewModel's property of LastNote and still provide a separate DataContext for the User Control?
(Keep in mind that the UserControl has dependency properties defined in its code-behind).
Thanks for any help with this.
Upvotes: 0
Views: 1692
Reputation: 1492
Give the MainView a name via the x:Name attribute. Then, for the RichText property, you can use a binding like: RichText={Binding ElementName=mainViewName, Path=DataContext.LastNote}
Really, you can use any control that has the MainViewModel as its DataContext in the ElementName property of the Binding. That may be easier since addressing controls generated by a DataTemplate by name can be tricky.
Here's an example of the general concept: Note how the TextBox bound to ChildName does so implicitly based on its DataContext, while TextBox next to it binds through the parentControl (using ElementName) to the Name property on its DataContext.
xaml:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="250">
<StackPanel x:Name="parentControl" Orientation="Vertical" DataContext="{Binding}">
<TextBox Text="{Binding Name}"/>
<StackPanel DataContext="{Binding ChildViewModel}" Margin="10">
<TextBox Text="{Binding ChildName}"/>
<TextBox Text="{Binding ElementName=parentControl, Path=DataContext.Name}"/>
</StackPanel>
</StackPanel>
</Window>
cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
public class PropertyNotifier : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propname)
{
var propChanged = PropertyChanged;
if (propChanged != null)
propChanged(this, new PropertyChangedEventArgs(propname));
}
}
public class MainViewModel : PropertyNotifier
{
private string _name = "MainViewModelProperty";
private ChildViewModel _childViewModel = new ChildViewModel();
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public ChildViewModel ChildViewModel
{
get { return _childViewModel; }
set
{
_childViewModel = value;
OnPropertyChanged("ChildViewModel");
}
}
}
public class ChildViewModel : PropertyNotifier
{
private string _childName = "ChildViewModelProperty";
public string ChildName
{
get { return _childName; }
set
{
_childName = value;
OnPropertyChanged("ChildName");
}
}
}
Upvotes: 1