1

i'm new to WPF and the MVVM pattern, i'm trying to make an app that uses several controls so i create each control separately and i am facing some difficulty for how to share data between controls

lets say i have a control that has a label and another control that contains a textbox, in the main window i want when i add the two custom controls i need the label control to show what i'm typing in the text box, i know how to implement that if i use the label and textbox directly in my window but i need that to solve similar issue, here is the Label Control

<UserControl x:Class="TestWPF2.Views.LabelControl" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Label ></Label> </Grid> </UserControl> 

TextBox Custom control

<UserControl x:Class="TestWPF2.Views.TextBoxControl" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <TextBox ></TextBox> </Grid> </UserControl> 

and this is the window code

<Window x:Class="TestWPF2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:V="clr-namespace:TestWPF2.Views" xmlns:Controls="clr-namespace:TestWPF2.Views" Title="MainWindow" Height="350" Width="525"> <DockPanel LastChildFill="True"> <Controls:TextBoxControl ></Controls:TextBoxControl> <Controls:LabelControl ></Controls:LabelControl> </DockPanel> </Window> 
3
  • As an aside, you should not be creating UserControl simply to wrap a single control like a Label or TextBox; just instantiate the Label or TextBox directly. I don't know if your actual code does this, or if this was just a simplified example. Commented Jan 21, 2014 at 14:10
  • Take a look at Simple Pattern for Creating Re-useable UserControls to do it the right way. Commented Jan 21, 2014 at 14:10
  • You should probably include the 'code behind' in your question Commented Jan 21, 2014 at 14:24

3 Answers 3

2

With binding, controls will inherit the datacontext of their parent.

If you set the window datacontext to "Model" (or the controls datacontext to "Model" if you need to keep it restrained) and that model has a property called "SomeText", you could bind the textbox and label as shown below:

<TextBox BorderBrush="Black" Text="{Binding Path=Model.SomeText,UpdateSourceTrigger=PropertyChanged}" /> 

If you need further info, please let me know. Bindings are a beast to start with.

You shouldn't need any code behind to wire up the controls.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for your answer,i know that control will inherit the datacontext of their parent unless you specify the datacontext but in my case i need to use different viewModel for each custom control, so my question is what is the best practice to do that , i can use a singleton property and the textbox and the label will be bound to the same property if im using singleton
I wouldn't use a singleton. If I was using 2 viewmodels, I would bind them both to the same (instance of a) model, so the changes would proliferate throughout. Have done something similar with BindableBase and CSLA. Haven't done much with PRISM, but assume you could use all MVVM frameworks in the same way.
0

Just knocked up an example that might be of use. Remember to use the output window to identify binding errors if needed.

In this example, my window is bound to a viewmodel, which has a property called 'Model'. The model has a Forename and surname property.

We have a label in the main window and a textbox in a control. Between this answer and my first, I'll let you finish it off to get it how you want.

Main Window Code (in this case the datacontext has been quickly set in code behind, though there are many ways to do it).

Code Behind

 public partial class BindingTest : Window { public BindingTest() { InitializeComponent(); Models.NamesModel nm = new Models.NamesModel(); nm.Forename = "Bill"; nm.Surname = "Gates"; ViewModels.NamesViewModel vm = new ViewModels.NamesViewModel(nm); this.DataContext = vm; } } 

Window

<Window x:Class="WPFTutSimple.BindingTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ctrl="clr-namespace:WPFTutSimple.UserControls" Title="BindingTest" Height="300" Width="300" > <StackPanel> <Label Content="Name"></Label> <Label Content="{Binding Path=Model.Surname}"></Label> <ctrl:TextBoxControl /> </StackPanel> </Window> 

User Control Code.

<UserControl x:Class="WPFTutSimple.UserControls.TextBoxControl" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <StackPanel> <TextBox Text="{Binding Path=Model.Surname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200" BorderBrush="Black" HorizontalAlignment="Left"></TextBox> </StackPanel> </UserControl> 

If you want/need to see what is going on in your usercontrols (and you are using WPF proper, not WinRT) you can tap into the DataContextChanged Event in the user control and check the 'e' values as the datacontext changes:

 public partial class TextBoxControl : UserControl { public TextBoxControl() { InitializeComponent(); this.DataContextChanged += TextBoxControl_DataContextChanged; } void TextBoxControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { //Set breakpoint here... } } 

Comments

0

you can use dependency properties to fit your usercontrols.

<UserControl x:Class="TestWPF2.Views.TextBoxControl" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" x:Name="uc"> <Grid> <TextBox Text="{Binding ElementName=uc, Path=MyText}"></TextBox> </Grid> </UserControl> 

codebehind add the dependency property

 public static readonly DependencyProperty MyTextProperty = DependencyProperty.Register("MyText", typeof(string), typeof(TextBoxControl), new FrameworkPropertyMetadata("")); public stringMyText { get { return (bool)GetValue(MyTextProperty); } set { SetValue(MyTextProperty, value); } } 

now you can use this control in any view like this:

 <Window x:Class="TestWPF2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:V="clr-namespace:TestWPF2.Views" xmlns:Controls="clr-namespace:TestWPF2.Views" Title="MainWindow" Height="350" Width="525"> <DockPanel LastChildFill="True"> <Controls:TextBoxControl MyText="{Binding Path=YourPropertyYouWannaBindTo}" /> <Controls:LabelControl ></Controls:LabelControl> </DockPanel> </Window> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.