How to properly bind a property to a DependencyObject?

Forrest Crawford 80 Reputation points
2024-11-02T23:22:51.38+00:00

I've got a window and a view model for that window. In that view model, I have a property called Description and it is updated every second. I also have a user control called CustomControl and it has a dependency property called Description that is bound to a textbox's text property. I'm attempting to have that user control in my main window with the Description property bound to the Description dependency property of the user control but it is not working. I do not get any error on the binding but the dependency is not being updated. See below for relevant code and here is a link to a git page for the example project.

MainWindow.xaml:

<Window x:Class="DependencyBindingTest.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:DependencyBindingTest"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <local:CustomControl Description="{Binding Description}" />
    </Grid>
</Window>

MainWindow.xaml.cs:


using System.Windows;

namespace DependencyBindingTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

ViewModel.cs:


using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace DependencyBindingTest
{
    public class ViewModel : INotifyPropertyChanged
    {
        private Random _random = new Random();

        private string _description = "asdf";

        public string Description
        {
            get { return _description; }
            set
            {
                if (_description != value)
                {
                    _description = value;
                    OnPropertyChanged();
                }
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        public ViewModel()
        {
            Task.Run(RunUpdateDescription);
        }

        private async Task RunUpdateDescription()
        {
            while (true)
            {
                UpdateDescription();
                await Task.Delay(1000);
            }
        }
        private async void UpdateDescription()
        {
            Description = "";

            for (int i = 0; i < 10; i++)
            {
                int random = _random.Next(65, 123);
                Char c = (Char)random;
                Description += $"{c}";
            }
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

CustomControl.xaml:

<UserControl x:Class="DependencyBindingTest.CustomControl"
             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:DependencyBindingTest"
             mc:Ignorable="d"
             d:DesignHeight="450"
             d:DesignWidth="800"
             DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}">
    <Grid>
        <TextBlock Text="{Binding Description}" />
    </Grid>
</UserControl>

CustomControl.xaml.cs:

using System.Windows;
using System.Windows.Controls;

namespace DependencyBindingTest
{
    /// <summary>
    /// Interaction logic for CustomControl.xaml
    /// </summary>
    public partial class CustomControl : UserControl
    {
        public string Description
        {
            get { return (string)GetValue(DescriptionProperty); }
            set { SetValue(DescriptionProperty, value); }
        }

        public static readonly DependencyProperty DescriptionProperty =
       DependencyProperty.Register(
           nameof(Description),
           typeof(string),
           typeof(CustomControl),
           new PropertyMetadata(null, OnDescriptionChanged));

        public CustomControl()
        {
            InitializeComponent();
        }

        private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            
        }
    }
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,003 questions
{count} votes

Accepted answer
  1. Viorel 118K Reputation points
    2024-11-03T07:11:29.5766667+00:00

    This seems to work:

    <local:CustomControl DataContext="{Binding}" Description="{Binding Description}" />
    
    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.