Augustin Bocken
Augustin Bocken

Reputation: 379

Binding on Dependency Property of UserControl

I'm trying to create UserControls to be able to reuse them later in the WPF application. I choose to build a small project to train myself, but I can't make it work.

The objective is to have a TextBox whose content will be sent as a Label Text with the click on a Button.

I've read and tried the solutions on those links :

But even the starting text I set in the constructor doesn't show up, and the button click does nothing at all.

Here are my files :

MyControl.xaml

<UserControl x:Class="WpfApplication1.MyControl"
             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:WpfApplication1"
             mc:Ignorable="d" 
             Name="control"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding TextBoxContent,ElementName=control}"/>
        <Button Content="Print Entry" Grid.Row="1" Command="{Binding ButtonCommmand,ElementName=control}"/>
        <Label Grid.Row="2" Content="{Binding LabelContent,ElementName=control}"/>
    </Grid>
</UserControl>

MyControl.xaml.cs

using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MyControl : UserControl
    {
        public MyControl()
        {
            InitializeComponent();
            ButtonCommmand = new RelayCommand(Action);
        }

        public string TextBoxContent
        {
            get
            {
                return (string)GetValue(TextBoxContentProperty);
            }
            set
            {
                SetValue(TextBoxContentProperty, value);
            }
        }
        public RelayCommand ButtonCommmand
        {
            get
            {
                return (RelayCommand)GetValue(ButtonCommandProperty);
            }
            set
            {
                SetValue(ButtonCommandProperty, value);
            }
        }

        public string LabelContent {
            get
            {
                return (string)GetValue(LabelContentProperty);
            }
            set
            {
                SetValue(LabelContentProperty, value);
            }
        }

        public void Action()
        {
            LabelContent = TextBoxContent;
        }

        public static readonly DependencyProperty TextBoxContentProperty = DependencyProperty.Register("TextBoxContent", typeof(string), typeof(MyControl), new PropertyMetadata(""));

        public static readonly DependencyProperty ButtonCommandProperty = DependencyProperty.Register("ButtonCommmand", typeof(RelayCommand), typeof(MyControl), new PropertyMetadata(null));

        public static readonly DependencyProperty LabelContentProperty = DependencyProperty.Register("LabelContent", typeof(string), typeof(MyControl), new PropertyMetadata(""));
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication1.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:local="clr-namespace:WpfApplication1"
        xmlns:control="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <control:MyControl DataContext="{Binding customControl}" TextBoxContent="{Binding Text,Mode=TwoWay}" LabelContent="{Binding EndText,Mode=TwoWay}" ButtonCommmand="{Binding Command,Mode=TwoWay}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        MyControl customControl = new MyControl();
        public MainWindow()
        {
            InitializeComponent();
            Command = new RelayCommand(Action);
            Text = "Testing... Testing... 1, 2, 3,...";
        }

        private string text;
        public string Text
        {
            get
            {
                return text;
            }
            set
            {
                text = value;
                NotifyPropertyChanged();
            }
        }
        private string endText;
        public string EndText
        {
            get
            {
                return endText;
            }
            set
            {
                endText = value;
                NotifyPropertyChanged();
            }
        }
        private RelayCommand command;
        public RelayCommand Command
        {
            get
            {
                return command;
            }
            set
            {
                command = value;
                NotifyPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void Action()
        {
            EndText = Text;
        }

        private void NotifyPropertyChanged([CallerMemberName]string PropertyName = "")
        {
            if (!String.IsNullOrEmpty(PropertyName))
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }
}

Thank you a lot for your help !

Upvotes: 2

Views: 1568

Answers (1)

mm8
mm8

Reputation: 169390

You are creating another instance of your UserControl in the code-behind of the window:

MyControl customControl = new MyControl();

What you want to do is to bind the properties of the UserControl that you have defined in your XAML to the properties of the window. For this to work you should set the DataContext of the window to itself:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Command = new RelayCommand(Action);
        Text = "Testing... Testing... 1, 2, 3,...";
    }
}

...and remove this from your XAML:

DataContext="{Binding customControl}" 

Upvotes: 1

Related Questions