Reputation: 1124
,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
Upvotes: 2
Views: 908
Reputation: 325
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());
});
}
Upvotes: 2
Reputation:
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.
Upvotes: 1
Reputation: 61379
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>
Upvotes: 1
Reputation:
You want to use ObservableCollection.CollectionChanged event in this case
Upvotes: 0