2

I have spent quite some time on this so seeking help.

Simple data binding with usercontrol with mvvm light does not work.

I have done the following.

  1. Created a MvvmLight (WPF451) project using VS 2015 and named it WpfDataBindingUserControlT1
  2. Added a UserControl and renamed it to SimpleUserControl.xaml
  3. Added some lables as a children(wraped in stackpanel) to the grid inside SimpleUserControl.xaml(All code is given below)
  4. Added a dependency properties in the code behind of the SimpleUserControl.xaml(SimpleUserControl.cs) so that these will help me in databinding.

The data binding simply does not work. I have pulled half of my hair on this so please help. I guess I am missing very simple on this.

The code is as follows.

  1. MainWindows.xaml

    <Window x:Class="WpfDataBindingUserControlT1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ignore="http://www.galasoft.ch/ignore" xmlns:local="clr-namespace:WpfDataBindingUserControlT1" mc:Ignorable="d ignore" Height="400" Width="300" Title="MVVM Light Application" DataContext="{Binding Main, Source={StaticResource Locator}}"> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Skins/MainSkin.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <Grid x:Name="LayoutRoot"> <TextBlock FontSize="36" FontWeight="Bold" Foreground="Purple" Text="{Binding WelcomeTitle}" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap" /> <local:SimpleUserControl DataContext="{Binding RelativeSource={RelativeSource Self}}" CellValue="{Binding WelcomeTitle}" /> </Grid> </Window> 
  2. MainWindow.cs ( I did not change any thing in this file.)

    using System.Windows; using WpfDataBindingUserControlT1.ViewModel; namespace WpfDataBindingUserControlT1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { /// <summary> /// Initializes a new instance of the MainWindow class. /// </summary> public MainWindow() { InitializeComponent(); Closing += (s, e) => ViewModelLocator.Cleanup(); } } } 
  3. SimpleUserControl.xaml

    <UserControl x:Class="WpfDataBindingUserControlT1.SimpleUserControl" 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:WpfDataBindingUserControlT1" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <StackPanel> <Label Content="This Prints" /> <Label Name="MyLable" Content="{Binding Path=CellValue}"></Label> <Label Content="This also Prints" /> </StackPanel> </Grid> </UserControl> 
  4. SimpleUserControl.cs (added a dependency prop)

    using System.Windows; using System.Windows.Controls; namespace WpfDataBindingUserControlT1 { /// <summary> /// Interaction logic for SimpleUserControl.xaml /// </summary> public partial class SimpleUserControl : UserControl { public string CellValue { get { return (string)GetValue(CellValueProperty); } set { SetValue(CellValueProperty, value); } } public static readonly DependencyProperty CellValueProperty = DependencyProperty.Register("CellValue", typeof(string), typeof(SimpleUserControl), new FrameworkPropertyMetadata { BindsTwoWayByDefault = true, }); public SimpleUserControl() { InitializeComponent(); } } } 
  5. MainViewModel.cs (I have not changed any thing in this)

    using GalaSoft.MvvmLight; using WpfDataBindingUserControlT1.Model; namespace WpfDataBindingUserControlT1.ViewModel { /// <summary> /// This class contains properties that the main View can data bind to. /// <para> /// See http://www.mvvmlight.net /// </para> /// </summary> public class MainViewModel : ViewModelBase { private readonly IDataService _dataService; /// <summary> /// The <see cref="WelcomeTitle" /> property's name. /// </summary> public const string WelcomeTitlePropertyName = "WelcomeTitle"; private string _welcomeTitle = string.Empty; /// <summary> /// Gets the WelcomeTitle property. /// Changes to that property's value raise the PropertyChanged event. /// </summary> public string WelcomeTitle { get { return _welcomeTitle; } set { Set(ref _welcomeTitle, value); } } /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel(IDataService dataService) { _dataService = dataService; _dataService.GetData( (item, error) => { if (error != null) { // Report error here return; } WelcomeTitle = item.Title; }); } ////public override void Cleanup() ////{ //// // Clean up if needed //// base.Cleanup(); ////} } } 
  6. ViewModelLocator.cs (I have not changed any thing in this as well.)

    /* In App.xaml: <Application.Resources> <vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:WpfDataBindingUserControlT1.ViewModel" x:Key="Locator" /> </Application.Resources> In the View: DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}" */ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Ioc; using Microsoft.Practices.ServiceLocation; using WpfDataBindingUserControlT1.Model; namespace WpfDataBindingUserControlT1.ViewModel { /// <summary> /// This class contains static references to all the view models in the /// application and provides an entry point for the bindings. /// <para> /// See http://www.mvvmlight.net /// </para> /// </summary> public class ViewModelLocator { static ViewModelLocator() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); if (ViewModelBase.IsInDesignModeStatic) { SimpleIoc.Default.Register<IDataService, Design.DesignDataService>(); } else { SimpleIoc.Default.Register<IDataService, DataService>(); } SimpleIoc.Default.Register<MainViewModel>(); } /// <summary> /// Gets the Main property. /// </summary> [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This non-static member is needed for data binding purposes.")] public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } } /// <summary> /// Cleans up all the resources. /// </summary> public static void Cleanup() { } } } 

1 Answer 1

4

Add this line to your SimpleUserControl.cs constructor

public SimpleUserControl() { InitializeComponent(); (this.Content as FrameworkElement).DataContext = this; } 

You're basically setting the DataContext of the first element in the UserControl.

Jerry Nixon has a great article on this here

UPDATE forgot to add get rid of the RelativeSource eg

<local:SimpleUserControl CellValue="{Binding WelcomeTitle}" /> 
Sign up to request clarification or add additional context in comments.

2 Comments

Its not working. But either way I have observed I get the following error System.Windows.Data Error: 40 : BindingExpression path error: 'WelcomeTitle' property not found on 'object' ''SimpleUserControl' (Name='')'. BindingExpression:Path=WelcomeTitle; DataItem='SimpleUserControl' (Name=''); target element is 'SimpleUserControl' (Name=''); target property is 'CellValue' (type 'String'). Not able to decipher whats wrong
see my update. Ive tested with your code and it works only difference being I dont use IDataService just hard coded string for WelcomeTitle

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.