2014-01-14 3 views
2

, когда я обновляю элемент в ObservableCollection «MyCollection» Я хочу, чтобы мой заказ TextBlock (выполнить функцию и изменить его текст, я думаю, что я должен вызвать функцию OnMYDataChanged:.Выполнить функцию в DependencyProperty

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

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

где

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     
    } 

Когда я изменить один элемент, OnMyDataChanged вызывается, но я получаю ошибку там: ссылка на объект требуется для не статического поля, метода или свойства

ответ

1

текстовое свойство не доступно, поскольку функция обратного вызова является статической.

Вам необходимо указать параметр obj в 'MyTextBlock' и передать этот указатель, чтобы вы могли получить доступ к свойствам вашего объекта.

+0

Это решило проблему! Спасибо! Считаете ли вы, что этот подход является более правильным, или будет лучше использовать IMultiValueConverter, связывающий MyText и containerSize? – Daniel

+1

Я думаю, что это отличное решение. Я не представляю сложные привязки. –

0

Вы хотите использовать ObservableCollection.CollectionChanged событие в этом случае

+0

Это будет работать только если INotifyPropertyChanged реализуется агрегированным типом объекта, и будет срабатывать, когда будет изменен элемент ANY, а не только элемент, которому привязан TextBlock. – BradleyDotNET

+0

Я думаю, я не понимаю, что они после :( –

+0

Означает ли это, что если я изменю один элемент, все текстовые блоки в ListBox будут запускать функцию? – Daniel

1

Ваш исходный объект должен реализовать INotifyPropertyChanged для этой работы (объект со свойством «MYTEXT»).

Существует отличная примерная реализация на MSDN.

Как и в сторону, ваш DataTemplate может содержаться в ListBox, вместо того, чтобы быть статический ресурс (может быть менее запутанным, если это единственное место, которое вы хотите использовать этот шаблон данных):

<ListBox> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+0

Внедрение INotifyPropertyChanged. Пожалуйста, взгляните на дополнительные данные. – Daniel

+0

Просто заметили что-то еще, вы привязываете свойство «Путь» вашего класса «MyTextBlock» вместо свойства «Текст». Это специально? – BradleyDotNET

+0

Это специально, так как если бы я привязал текст, я бы не смог измените его. – Daniel

0

Чтобы добавить логику в выполнении DependencyProperty, вы можете определить DependencyPropertyDescriptor для каждого DependencyProperty и добавить AddValueChanged вызов с необходимой логикой для этого в конструкторе вашего пользовательского класса. Если у вас есть пользовательский класс сетки под названием DefinableGrid со свойством Столбцов, результат затем (с помощью C# 6 в нулевом условном операторе ?.):

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()); 
     }); 
    } 
Смежные вопросы