-1

I have a WPF application where I need to do something like that :

<ItemsControl x:Name="lstProducts">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding ProductName}" />
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

I set the ItemsSource in code like this : lstProducts.ItemsSource = MyEFContext.Products;

Up to now everything is working fine. Now I want to use my own UserControl to display a product instead of the TextBlock like that.

<ItemsControl x:Name="lstProducts">
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <my:ProductItemCtl ProductName="{Binding ProductName}" />
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

In my userControl, I created a DependencyProperty like that (see below) where I set the ProductName in the OnProductNameChanged callback.

The TextBlock in my usercontrol is not updated when binding the ItemsControl, and the callback is not launched.

#region ProductName

        /// <summary>
        /// ProductName Dependency Property
        /// </summary>
        public static readonly DependencyProperty ProductNameProperty =
            DependencyProperty.Register("ProductName", typeof(String), typeof(ProductItemCtl),
                new FrameworkPropertyMetadata("",
                    new PropertyChangedCallback(OnProductNameChanged)));

        /// <summary>
        /// Gets or sets the ProductName property. This dependency property 
        /// indicates ....
        /// </summary>
        public String ProductName
        {
            get { return (String)GetValue(ProductNameProperty); }
            set {  SetValue(ProductNameProperty, value); }
        }

        /// <summary>
        /// Handles changes to the ProductName property.
        /// </summary>
        private static void OnProductNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ProductItemCtl target = (ProductItemCtl)d;
            String oldProductName = (String)e.OldValue;
            String newProductName = target.ProductName;
            target.OnProductNameChanged(oldProductName, newProductName);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the ProductName property.
        /// </summary>
        protected virtual void OnProductNameChanged(String oldProductName, String newProductName)
        {
            // Set Product Name in the display Here!
            this.txtProductName.Text = newProductName;
        }

        #endregion
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
danbord
  • 3,605
  • 3
  • 33
  • 49
  • 1
    Does adding Mode=TwoWay to your binding on your user control help? Also, why are you setting the text of your textbox in code (in OnProductNameChanged)? Why not bind it? – Matt Burland Apr 17 '12 at 19:41
  • 1
    Doesn't the line `DependencyProperty.Register("ProductName", typeof(String), typeof(AchatItem)` should actually have `typeof(ProductItemCtl)` instead of `typeof(AchatItem)`? – Adi Lester Apr 17 '12 at 19:45
  • No TwoWay does not change anything. I simplified the code here just to isolate the problem. In real need to do a lot more things than just setting the Text value. – danbord Apr 17 '12 at 19:45
  • Good call Lester, but that's not the issue. Leftovers from trying to simplify my example. I modified my example code. Thanks – danbord Apr 17 '12 at 19:49
  • 1
    Are you getting any binding errors in the output window? – Matt Burland Apr 17 '12 at 19:49
  • Nope, It just never update my textbox. the this.txtProductName.Text = newProductName; is never called – danbord Apr 17 '12 at 19:50
  • 1
    The code you posted works fine for me. You should make sure that you didn't drop the code that actually causes this problem when you simplified it. – Adi Lester Apr 17 '12 at 20:02

2 Answers2

0

Not an answer, but i can't write this as comment. What happens if you simplify your code like this:

public static readonly DependencyProperty ProductNameProperty = DependencyProperty.Register(
    "ProductName", typeof(string), typeof(ProductItemCtl), 
    new FrameworkPropertyMetadata(string.Empty,
        (o, e) => ((ProductItemCtl)o).txtProductName.Text = (string)e.NewValue)); 
Clemens
  • 123,504
  • 12
  • 155
  • 268
0

Arrrghhh got it... I had this.ProductName = ""; in the constructor of my UserControl

I wasted so much time on this... And sorry for wasting all of yours.

Since I found out by trying your code Clemens I will mark your answer as "Answered".

thanks everyone.

danbord
  • 3,605
  • 3
  • 33
  • 49