WPF UserControl - Property not fired when binded value changed

Vincent Vega 0 Reputation points
2025-05-22T14:02:23.8+00:00

Hi out there!

I created a UserControl an would like to do some logical stuff when the property "MyText" of that UserControl ist changed.

From my Master Window I would like to set a property (or dependency property) to trigger that change. When I set the property directly by name everything works like expected (Name: DirectCalledControl) . But when I try to set the new value with a binding in xaml, the text is updated, but the logik behind ist not fired. In my case the new datetime is not added to the text.

I will use a Control like that in an MVVM app. So it would be nice to do that over propertychanged. How can I make it?

I tried many, many things but nothing worked. I also tried different variations with datacontext and different modes (two way), but also without luck.

UserControl

<UserControl x:Class="WpfUserControlTest.MyTestUserControl"
             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:WpfUserControlTest"
             mc:Ignorable="d" 
             x:Name="TestUCName"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <StackPanel>
        <TextBlock Text="UserControl from Project"
                   FontSize="26"/>
        <TextBlock Text="{Binding MyText, ElementName=TestUCName}"
           FontSize="24"/>
        </StackPanel>
    </Grid>
</UserControl>
namespace WpfUserControlTest
{
    public partial class MyTestUserControl : UserControl
    {
        public MyTestUserControl()
        {
            InitializeComponent();
        }
        public string MyText
        {
            get { return (string)GetValue(MyTextProperty); }
            set { SetValue(MyTextProperty, Changer(value));}
        }
        // Using a DependencyProperty as the backing store for MyText.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyTextProperty =
            DependencyProperty.Register("MyText", typeof(string), typeof(MyTestUserControl), new PropertyMetadata("Hallo Welt (a simple default Property value from CodeBehind)"));
        private static string Changer(string someString)
        {
            // This should happen wenn MyText changes, but never will be fired
            return someString + " -- " + DateTime.Now.ToString();
        }
   }
}

Window

<Window x:Class="WpfUserControlTest.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:WpfUserControlTest"
        xmlns:ucl="clr-namespace:WpfUserControlTestControlLibrary;assembly=WpfUserControlTestControlLibrary"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        x:Name="Test"
        >
    <Grid>
        <!--DataContext="{Binding RelativeSource={RelativeSource Self}}"-->
        <StackPanel>
            <Button Content="Change Textblock" Click="Button_Click"/>
            <TextBlock Text="AppStart"/>
            <local:MyTestUserControl 
                Margin="10 20 0 0"
                Background="Beige"
                MyText="{Binding MyTextMaster, ElementName=Test}"/>
            <local:MyTestUserControl 
                x:Name="DirectCalledControl"
                Margin="10 20 0 0"
                Background="Beige"
                MyText="{Binding MyTextMaster, ElementName=Test}"/>
        </StackPanel>
    </Grid>
</Window>
namespace WpfUserControlTest
{
    public partial class MainWindow : Window
    {
        int Counter = 0;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyTextMaster = "Number: " + Counter.ToString();
            DirectCalledControl.MyText = MyTextMaster;
            Counter++;
        }
        public string MyTextMaster
        {
            get { return (string)GetValue(MyTextMasterProperty); }
            set { SetValue(MyTextMasterProperty, value); }
        }

        public static readonly DependencyProperty MyTextMasterProperty =
            DependencyProperty.Register("MyTextMaster", typeof(string), typeof(MainWindow), new PropertyMetadata("Initial value from MasterView"));
    }
}

Developer technologies XAML
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Viorel 122.5K Reputation points
    2025-05-22T17:02:18.06+00:00

    Try these modifications:

    public string MyText
    {
        get { return (string)GetValue( MyTextProperty ); }
        set { SetValue( MyTextProperty, value ); }
    }
    
    public static readonly DependencyProperty MyTextProperty =
        DependencyProperty.Register( "MyText", typeof( string ), typeof( MyTestUserControl ),
            new PropertyMetadata( "Hallo Welt (a simple default Property value from CodeBehind)", null, CoerceValue ) );
    
    private static object CoerceValue( DependencyObject d, object baseValue )
    {
        return Changer( (string)baseValue );
    }
    

  2. Vincent Vega 0 Reputation points
    2025-05-23T05:31:01.8+00:00

    After testing in real life I recognizied that my example was not that good. My goal is to change a non static value inside the UserControl. I've changed the CodeBehind of my UserControl to fit my needs. Hopefully there ist a solution for this.

    In real life i got a Filepath of a multipage TIFF, load as System.Drawing.Image, show the first page. Then I can change the shown page und rotate the tiff. My Example ist the Part of loading a new Image. The rest is inside the UserControl. Everything works exept using Binding in MVVM.

    btw: I tried to edit my question above, but after saving my changes where not shown. so i double post in this answer. sorry for that.

    //------ new Version -------
    namespace WpfUserControlTest
    {
        public partial class MyTestUserControl : UserControl
        {
            int internalCounter = 0;
    
            public MyTestUserControl()
            {
                InitializeComponent();
            }
    
            public string MyText
            {
                get { return (string)GetValue(MyTextProperty); }
                set { SetValue(MyTextProperty, ChangerNonStatic(value)); }
            }
    
            public static readonly DependencyProperty MyTextProperty =
                DependencyProperty.Register("MyText", typeof(string), typeof(MyTestUserControl), new PropertyMetadata("Hallo Welt (a simple default Property value from CodeBehind)"));
    
    
            private string ChangerNonStatic(string someString)
            {
                // This should happen wenn MyText Binding changes, but never will be fired. Only fired when setting the Property directly.
                someString += $"-- intValue:{internalCounter++} -- {DateTime.Now.ToString()}";
                return someString;
            }
        }
    }
    
    
    0 comments No comments

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.