How to implement WPF Binding programmatically (not XAML) with TwoWay binding mode?

Jörg Debus 66 Reputation points
2023-01-19T16:09:47.65+00:00

I have implemented some Dependency Properties in a c# class A as documented to mimic a very simple Control. In class B the Bindings and CLR Properties are implemented using the INotifyPropertyChange interface. Sending data from B to A works fine with binding mode OneWay. Sending data from B to A for updating and receiving the changed data back in B using the same DP with TwoWay mode results in the original data from B sent back from A.

Some help how to code the Receive/Update/Sentback logic in class A is highly appreciated.

Regards

Jörg

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,396 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,676 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Hui Liu-MSFT 40,266 Reputation points Microsoft Vendor
    2023-01-20T03:26:06.4066667+00:00

    You could refer to the following code.

    Custom Control:

    public class AControl1 : Control
        {
            public static readonly DependencyProperty TestPropProperty =
            DependencyProperty.Register("TestProp", typeof(string), typeof(AControl1), new UIPropertyMetadata(null));
    
            public string TestProp
            {
                get { return (string)GetValue(TestPropProperty); }
                set { SetValue(TestPropProperty, value); }
            }
    
            static AControl1()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(AControl1), new FrameworkPropertyMetadata(typeof(AControl1)));
            }
        }
    
    
    
    
    
    
    

    Generic.xaml:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DatabindingCodebehind">
    
    
        <Style TargetType="{x:Type local:AControl1}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:AControl1}">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                            <StackPanel>
                                <TextBlock Text="Testing..."  Height="50"/>
                                <Separator />
                                <Label Height="50" Content="{Binding TestProp, RelativeSource={RelativeSource Mode=TemplatedParent}}"  />
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    

    MainWindow.xaml:

    <Grid x:Name="grid">
    </Grid>
    

    MainWindow.xaml.cs:

    
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Media;
    
    namespace DatabindingCodebehind
    {
        public partial class MainWindow : Window,INotifyPropertyChanged
        {
    
            AControl1 a = new AControl1();
            public MainWindow()
            {
                InitializeComponent();
                grid.Children .Add (a);
                a.Height = 150;
                a.Width = 100;
                a.Background = Brushes.AliceBlue;
                TestObject myDataObject = new TestObject("name1");
                Binding myBinding = new Binding("Name");
                myBinding.Source = myDataObject;
                myBinding.Mode = BindingMode.TwoWay;
                a.SetBinding(AControl1.TestPropProperty, myBinding);
            }
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged([CallerMemberName] string name = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
        }
    
        public class TestObject : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(string PropertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
            public TestObject() { }
            public TestObject(string Name) 
            {
                _Name = Name;
            }
            private int _id;
            public int Id
            {
                get { return _id; }
                set { _id = value; OnPropertyChanged("Id"); }
            }
    
            private string _Name;
            public string Name
            {
                get { return _Name; }
                set { _Name = value; OnPropertyChanged("Name"); }
            }
        }
    }
    
    

    The result:

    User's image


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.