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.
- Created a MvvmLight (WPF451) project using VS 2015 and named it WpfDataBindingUserControlT1
- Added a UserControl and renamed it to SimpleUserControl.xaml
- Added some lables as a children(wraped in stackpanel) to the grid inside SimpleUserControl.xaml(All code is given below)
- 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.
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>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(); } } }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>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(); } } }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(); ////} } }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() { } } }