Click here to Skip to main content
15,889,876 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am in a very basic problem.
I have created a user control, say sample like this :

XML
<UserControl x:Class="TextCalc.txtItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBox Name="txtMessage" Text="{Binding Message, ElementName=root}" Width="30" Height="20"></TextBox>
    </Grid>
</UserControl>


I have created a DependencyProperty named Message which I want to work with DataBinding. The Code looks like :

C#
public partial class txtItem : UserControl
{
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message",typeof(String),typeof(txtItem), new UIPropertyMetadata("0", textChangedCallback));
        private static void textChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            txtItem input = (txtItem)d;
            input.txtMessage.Text = e.NewValue as String;
        }
        public string Message
        {
            get { return (string)GetValue(MessageProperty); }
            set { SetValue(MessageProperty, value); }
        }
 }


Now once I built the control, I want this control to work with Databinding just like how normal TextBox works. In my Window, I used this as :

XML
<ListBox x:Name="lstBox" ItemsSource="{Binding}">
           <ListBox.ItemTemplate>
               <DataTemplate>
                   <StackPanel Orientation="Horizontal">
                       <TextBlock Text="{Binding Name}" />
                       <local:txtItem HorizontalAlignment="Center" VerticalAlignment="Center"  Width="50" Message="{Binding Value}"/>
                   </StackPanel>
               </DataTemplate>
           </ListBox.ItemTemplate>
       </ListBox>



From the codebehind :
private List<Element> items = null;
C#
private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.items = new List<Element>();
            items.Add(new Element { Name = "Abhishek", Value = "300" });
            this.lstBox.DataContext = items;
        }


The Element class is also implemented from INotifyPropertyChanged :
C#
public class Element : INotifyPropertyChanged
    {
        private string _Name;
        public string Name
        {
            get
            {
                return this._Name;
            }
            set
            {
                this._Name = value;
                this.OnPropertyChanged("Name");
            }
        }
        private string _Value;
        public string Value
        {
            get
            {
                return this._Value;
            }
            set
            {
                this._Value = value;
                this.OnPropertyChanged("Value");
            }
        }

        #region INotifyPropertyChanged Members
        public virtual void OnPropertyChanged(string info)
        {
            if(this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }



Now when I change the data within the Textbox that comes within the UserControl, it doesnt update the actual object. I have even implemented the UserControl from INotifyPropertyChanged, and invoked the event when the value is changed on the TextBox, but alas, it didnt worked for me. Can anyone help me in this regard.

If you want to see the code you can download from here:
TextCalc.zip (80 KB)
Posted

Hey Abhishek,

You missed something. Generally your code should work but there was a small mistake. Here is the code:

XML
<ListBox x:Name="lstBox"
         ItemsSource="{Binding}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}" />
                <local:txtItem HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Width="50"
                               Message="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>


Your first mistake was here:

XML
<local:txtItem HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       Width="50"
                                       Message="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>


You didn't bind it for twoway mode. :(

Second mistake is in your UserControl. Samething, binding was not proper. Here is the code:

<UserControl x:Name="userControl" x:Class="TextCalc.txtItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBox Name="txtMessage" Text="{Binding Message, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="30" Height="20"></TextBox>
    </Grid>
</UserControl>


Let me know if it resolves your issue. Don't forget to "Mark As Answer" if it resolves your query.

Thanks & Regards,
Kunal
 
Share this answer
 
Comments
Abhishek Sur 28-May-10 16:16pm    
Wow kunal, it worked...

The only thing that I missed out was Mode=TwoWay. I made it work without UpdateSourceTrigger=PropertyChanged.

Thank you so much for your help. I have marked it as answered. Cheers.
Try by creating an object of type ObservableCollection.
You then fill this object with actual data values and bind it to your listbox.

public ObservableCollection<<Element>> MyCollection
{
    get
    {
        return this._myCollection;
    }
    set
    {
        this._Value = value;
        this.OnPropertyChanged("MyCollection");
    }
}


Note: I had to use two <<>> for the Element class above as if I used one it was not appearing.

<listbox x:name="lstBox" itemssource="{Binding <b>MyCollection</b>}" xmlns:x="#unknown">
           <listbox.itemtemplate>
               <datatemplate>
                   <stackpanel orientation="Horizontal">
                       <textblock text="{Binding Name}" />
                       <local:txtitem horizontalalignment="Center" verticalalignment="Center" width="50" message="{Binding Value}" xmlns:local="#unknown" />
                   </stackpanel>
               </datatemplate>
           </listbox.itemtemplate>
       </listbox>


Listbox and Textbox binding are different as ListBox binds to an itemssource collection.

For a simple example, have a look here.
 
Share this answer
 
Comments
Abhishek Sur 24-May-10 5:44am    
Abhinav,

Even though I have tried the same, but it isn't working for me.

I think there must be something wrong inside the UserControl, or something I missed out. Can you download the Code and take a look.

Thanks in advance.
Abhishek Sur 28-May-10 16:16pm    
Reason for my vote of 2
Didnt get the Right Answer here. Sorry.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900