2013-06-29 1 views
1

임 -데이터 컨텍스트 이벤트에 바인드 된 이벤트 설정기를 가질 수 있습니까? 이런 식으로 뭔가를 만들려고

enter image description here

나는 점의 관측 컬렉션이 있습니다. 각 점에는 위치와 색상이 있습니다. 점 위치 나 색상이 변경되면 (알림 변경), 배경 그라디언트를 다시 칠하고 싶습니다. 현재 나는 포인트 컨트롤에 슬라이더가 있고, 그라디언트가 처음에 그려지는 itemscontrol을 가지고 있습니다. 지금, 나는이 '점'화재에하여 PropertyChanged 이벤트, 내가 그라디언트를 칠 수 있도록 때 내 시야의 뒤에 코드에서 함수를 호출하는 방법을 알고 싶어요. 임이 이벤트 설정자가 어떻게 든 사용될 수 있는지 궁금한가요? 나는 뒤에 코드에 가입하여 PropertyChanged 이벤트를 할 수있는 동안

, 나는 XAML에서 할 싶습니다? 내가 아닌 다른 솔루션하시기 바랍니다 위의 특정 문제에 대한 답변을 얻을 수 있다면 특별히 수동으로 다른 이유로 뒤에 코드에서 다시 칠이 방법을 먹고 싶어, 그래서 :

있습니다.

답변

1

첨부 된 속성을 만들어 PropertyChanged 이벤트에 가입하면 DataContext 속성 값을 구독 할 수 있습니다.

public static class Props 
{ 
    public static DependencyProperty OnPropertyChangedProperty = DependencyProperty.RegisterAttached(
     "OnPropertyChanged", typeof(PropertyChangedEventHandler), typeof(Props), 
     new PropertyMetadata(OnPropertyChangedPropertyChanged)); 

    public static PropertyChangedEventHandler GetOnPropertyChanged (DependencyObject d) 
    { 
     return (PropertyChangedEventHandler)d.GetValue(OnPropertyChangedProperty); 
    } 

    public static void SetOnPropertyChanged (DependencyObject d, PropertyChangedEventHandler value) 
    { 
     d.SetValue(OnPropertyChangedProperty, value); 
    } 

    private static void OnPropertyChangedPropertyChanged (DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var inpc = (INotifyPropertyChanged)((FrameworkElement)d).DataContext; 
     if (inpc == null) 
      throw new ArgumentException("DataContext of the framework element must not be null."); 
     var oldChanged = (PropertyChangedEventHandler)e.OldValue; 
     if (oldChanged != null) 
      inpc.PropertyChanged -= oldChanged; 
     var newChanged = (PropertyChangedEventHandler)e.NewValue; 
     if (newChanged != null) 
      inpc.PropertyChanged += newChanged; 
    } 
} 

사용법 :

<Window x:Class="So17382721PropertyChangedXaml.MainWindow" x:Name="root" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:So17382721PropertyChangedXaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type local:Foo}"> 
      <!-- Here, we subscribe to DataContext.PropertyChanged; 
       handler is defined in the MainWindow class --> 
      <Grid local:Props.OnPropertyChanged="{Binding FooPropertyChanged, ElementName=root}"> 
       <TextBox Text="{Binding Bar, UpdateSourceTrigger=PropertyChanged}"/> 
      </Grid> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <ItemsControl ItemsSource="{Binding Foos, ElementName=root}"/> 
    </Grid> 
</Window> 

코드 숨김

using System; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using System.Windows; 

namespace So17382721PropertyChangedXaml 
{ 
    public partial class MainWindow 
    { 
     public ObservableCollection<Foo> Foos { get; private set; } 

     public MainWindow() 
     { 
      Foos = new ObservableCollection<Foo> { 
       new Foo { Bar = "1" }, 
       new Foo { Bar = "2" }, 
       new Foo { Bar = "3" }, 
      }; 
      InitializeComponent(); 
     } 

     private void OnFooPropertyChanged (object sender, PropertyChangedEventArgs e) 
     { 
      MessageBox.Show(this, string.Format("{0} of {1} changed.", e.PropertyName, sender)); 
     } 

     // Subscribing to non-RoutedEvents in XAML is not straightforward, but we can define a property 
     public PropertyChangedEventHandler FooPropertyChanged 
     { 
      get { return OnFooPropertyChanged; } 
     } 
    } 

    public class Foo : INotifyPropertyChanged 
    { 
     private string _bar; 
     public string Bar 
     { 
      get { return _bar; } 
      set 
      { 
       _bar = value; 
       OnPropertyChanged(); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) 
     { 
      var handler = PropertyChanged; 
      if (handler != null) 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

참고 : 연결된 속성 Props.OnPropertyChangedDataContext하지 수명 기간 동안 변경되고 이미 지정된 것으로 기대하고있다. DataContextChanged 이벤트를 처리하는 것은 필요하다면 외풍으로 남습니다.

+0

좋아! 고맙습니다. 또한 "CallerMemberName"을 소개해 주셔서 감사합니다. D – pastillman

관련 문제