WPF user control binding not worked

hossein tavakoli 471 Reputation points
2022-05-26T09:38:20.367+00:00

Hi dears,
I created an user control in my WPF app.
When I want to bind a data to my control it's not working.

my user control :

<UserControl x:Class="StoreManager.UserControls.DateTimePicker2"
             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"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="300" >
    <Grid>
        <TextBox x:Name="myTextBox" TextChanged="myTextBox_TextChanged"/>
    </Grid>
</UserControl>


public partial class DateTimePicker2 : UserControl
{
        public DateTimePicker2()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty SelectedDateProperty = DependencyProperty.Register(nameof(SelectedDate), typeof(DateTime), typeof(DateTimePicker2), new PropertyMetadata(DateTime.Now));

        public DateTime SelectedDate
        {
            get { return (DateTime)GetValue(SelectedDateProperty); }
            set
            {
                SetValue(SelectedDateProperty, value);
                if(!IsSettingDateTime)
                    myTextBox.Text = value.ToShortDateString();
            }
        }

        private bool IsSettingDateTime=false;    
        private void myTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            IsSettingDateTime=true;
            SelectedDate = DateTime.Parse(myTextBox.Text);
            IsSettingDateTime=false;
        }
}

my window :

 <Window x:Class="StoreManager.frmSample"
        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:StoreManager"
        mc:Ignorable="d"
        xmlns:userControl="clr-namespace:StoreManager.UserControls"
        Title="MainWindow" Height="400" Width="800" FlowDirection="RightToLeft" WindowStartupLocation="CenterScreen">
    <Window.DataContext>
        <local:DateHelper/>
    </Window.DataContext>
    <Grid FlowDirection="RightToLeft" >
        <StackPanel>
            <userControl:DateTimePicker2 x:Name="myControl" SelectedDate="{Binding dateTime,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="60" Width="300"/>
            <Button Content="Add 10 Days" Click="Button_Click" Margin="10" Width="300"/>
        </StackPanel>
    </Grid>
</Window>


namespace StoreManager
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class frmSample : Window
    {
        DateHelper dtContext;
        public frmSample()
        {
            InitializeComponent();
            dtContext = (DateHelper)DataContext;
            dtContext.dateTime = System.DateTime.Now;
            dtContext.myString = "Date";
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            dtContext.dateTime= dtContext.dateTime.AddDays(10);
            dtContext.myString = dtContext.dateTime.ToShortDateString();
        }
    }

    public class DateHelper: INotifyPropertyChanged
    {
        private DateTime _dateTime;
        public DateTime dateTime
        {
            get { return _dateTime; }
            set
            {
                _dateTime = value;
                OnPropertyChanged(nameof(dateTime));
            }
        }

        private string _myString;
        public string myString
        {
            get { return _myString; }
            set
            {
                _myString = value;
                OnPropertyChanged(nameof(myString));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}
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,765 questions
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.
10,886 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
806 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Hui Liu-MSFT 48,521 Reputation points Microsoft Vendor
    2022-05-27T03:04:58.727+00:00

    You could use the following code.
    UserControl.xaml:

     <Grid>  
            <TextBox x:Name="myTextBox" Text="{Binding SelectedDate,  
                    RelativeSource={RelativeSource AncestorType=UserControl}}"/>  
        </Grid>  
    

    UserControl.xaml.cs:

    using System;  
    using System.Windows;  
    using System.Windows.Controls;  
    
    namespace UserControlWorking  
    {  
      public partial class DateTimePicker2 : UserControl  
      {  
        public DateTimePicker2()  
        {  
          InitializeComponent();  
        }  
        public static readonly DependencyProperty SelectedDateProperty =   
          DependencyProperty.Register(nameof(SelectedDate), typeof(DateTime), typeof(DateTimePicker2),  
            new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));  
    
        public DateTime SelectedDate  
        {  
          get { return (DateTime)GetValue(SelectedDateProperty); }  
          set  
          {  
            SetValue(SelectedDateProperty, value);  
    
          }  
        }  
    
      }  
    }  
    

    MainWindow.xaml:

    <Window.DataContext>  
            <local:DateHelper/>  
        </Window.DataContext>  
        <Grid FlowDirection="RightToLeft" >  
            <StackPanel>  
                <local:DateTimePicker2 x:Name="myControl" SelectedDate="{Binding dateTime,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Height="60" Width="300"/>  
                <Button Content="Add 10 Days" Click="Button_Click" Margin="10" Width="300"/>  
            </StackPanel>  
        </Grid>  
    

    MainWindow.xaml.cs:

    using System;  
    using System.ComponentModel;  
    using System.Windows;  
    namespace UserControlWorking  
    {  
      public partial class MainWindow : Window  
      {  
        DateHelper dtContext;  
        public MainWindow()  
        {  
    
          InitializeComponent();  
          dtContext =  new DateHelper();  
          DataContext=dtContext;  
          dtContext.dateTime = System.DateTime.Now;  
          dtContext.myString = "Date";  
        }  
        private void Button_Click(object sender, RoutedEventArgs e)  
        {  
          dtContext.dateTime = dtContext.dateTime.AddDays(10);  
          dtContext.myString = dtContext.dateTime.ToShortDateString();  
        }  
      }  
      public class DateHelper : INotifyPropertyChanged  
      {  
        private DateTime _dateTime;  
        public DateTime dateTime  
        {  
          get { return _dateTime; }  
          set  
          {  
            _dateTime = value;  
            OnPropertyChanged(nameof(dateTime));  
          }  
        }  
    
        private string _myString;  
        public string myString  
        {  
          get { return _myString; }  
          set  
          {  
            _myString = value;  
            OnPropertyChanged(nameof(myString));  
          }  
        }  
    
        public event PropertyChangedEventHandler PropertyChanged;  
        public virtual void OnPropertyChanged(string propertyName)  
        {  
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
        }  
    
      }  
    }  
    

    The result:
    206016-image.png
    206033-image.png


    If the response is helpful, please click "Accept Answer" and upvote it.
     Note: Please follow the steps in our [documentation][5] to enable e-mail notifications if you want to receive the related email notification for this thread. 

    [5]: https://learn.microsoft.com/en-us/answers/articles/67444/email-notifications.html

    0 comments No comments

  2. hossein tavakoli 471 Reputation points
    2022-06-16T06:55:52.8+00:00

    Its worked for me, but there is a problem.

    public DateTime SelectedDate  
         {  
           get { return (DateTime)GetValue(SelectedDateProperty); }  
           set  
           {  
             SetValue(SelectedDateProperty, value);  
             SelectedDate_Changed(null,null);  
           }  
         }  
    

    When I change SelectedDate programmatically it run SelectedDate_Changed(null,null) method correctly, but when SelectedDate change with binding it don't run SelectedDate_Changed(null,null) method.

    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.