Question

,When I update an item in observableCollection "MyCollection" I want my custom TextBlock ( to execute function and modify its text. I think I should call function OnMYDataChanged:

<ListBox ItemsSource="{Binding MyCollection}" ItemTemplate="{StaticResource MyTemplate}" >

<DataTemplate x:Key="MyTemplate"  >
  <Grid >...
    <local:MyTextBlock Path="{Binding MyText}"  />

where

public class MyTextBlock : TextBlock
 {
    public string Path
    {  get {return (string)GetValue(PathProperty);}
       set { SetValue(PathProperty, value); }
    }
    public static readonly DependencyProperty PathProperty =
       DependencyProperty.Register("Path", typeof(string), typeof(MyTextBlock), new PropertyMetadata(OnMyDataChanged));

    static void OnMyDataChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) {
      Text = DoSomethingWithText(); //Does not work                   
    }

When I change one item, OnMyDataChanged gets called, but I get error there: An object reference is required for the non-static field, method, or property

Was it helpful?

Solution 2

The text property is not acessible because the callback function is static.

You need to cast the obj parameter to 'MyTextBlock', and throug that pointer you can access your object's properties.

OTHER TIPS

To add logic to the execution of a DependencyProperty, you can define a DependencyPropertyDescriptor for each DependencyProperty and add an AddValueChanged call with the necessary logic to it in your custom class's constructor. If you have a custom Grid class called DefinableGrid with a Columns property, the result is then (using C# 6's null-conditional operator ?.):

    public int Columns
    {
        get { return (int) GetValue(ColumnsDependencyProperty); }
        set { SetValue(ColumnsDependencyProperty, value); }
    }
    public static readonly DependencyProperty ColumnsDependencyProperty =
        DependencyProperty.Register(nameof(Columns), typeof(int), typeof(DefinableGrid), new PropertyMetadata(0));

    DependencyPropertyDescriptor ColumnsPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ColumnsDependencyProperty, typeof(DefinableGrid));

    public GridEx()
    {
        ColumnsPropertyDescriptor?.AddValueChanged(this, delegate
        {
            ColumnDefinitions.Clear();
            for (int i = 0; i < Columns; i++)
                ColumnDefinitions.Add(new ColumnDefinition());
        });
    }

Your source object needs to implement INotifyPropertyChanged for this to work (the object with the "MyText" property).

There is a great example implementation on MSDN.

As an aside, your datatemplate can be contained within the ListBox instead of being a static resource (might be less confusing if this is the only spot you want to use that data template):

<ListBox>
   <ListBox.ItemTemplate>
       <DataTemplate>
       </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

You want to use ObservableCollection.CollectionChanged event in this case

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top