2011-09-07 5 views
1

나는이 guy in the Silverlight Forum으로 정확한 문제를 가지고 허용 대답은 :이 경우PropertyChangedCallback 일단

은, 당신의 재산은 실제로 값을 변경하지 않았다. 당신은 당신의 목록에 뭔가를 추가,하지만 하는 DependencyProperty 메커니즘이 실제 값 ( 목록을 참조)이 변경되지 않았 음을보고, 그것은 당신는 onChanged 핸들러를 제기하지 않은 경우 목록이 너무 같은 목록입니다

대단한 설명이지만이 문제를 해결할 수있는 대답이 아닙니다. Google에서 WPF에 대한 많은 제안을 찾을 수 있지만 Silverlight에 대해서는 제안하지 않습니다.

이 문제는 다음과 같이 설명됩니다. 변수를 초기화 할 때 호출되는 DependencyProperty가 있지만 그 이후에는 아무 것도 업데이트되지 않습니다.

public partial class MyGrid : UserControl 
{ 
    public MyGrid() 
    { 
     InitializeComponent(); 
    } 

    public static readonly DependencyProperty ShapesProperty = DependencyProperty.Register(
      "Shapes", typeof(ObservableCollection<ModelItem>), typeof(MyGrid), new PropertyMetadata(OnShapesPropertyChanged)); 

    public ObservableCollection<ModelItem> Shapes 
    { 
     private get { return (ObservableCollection<ModelItem>)GetValue(ShapesProperty); } 
     set { SetValue(ShapesProperty, value); } 
    } 

    private static void OnShapesPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
    { 
     ((MyGrid)o).OnShapesPropertyChanged(e); //Fire Only Once 
    } 

    private void OnShapesPropertyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     dg.ItemsSource = e.NewValue as ObservableCollection<ModelItem>; 
    } 


} 

//-------- 
public class ViewModel : INotifyPropertyChanged 
{ 
    public Model Model { get; set; } 
    public RelayCommand cmd; 
    public ObservableCollection<ModelItem> ModelItemCollection 
    { 
     get 
     { 
      return Model.ModelItem; 
     } 
    } 

    public ViewModel() 
    { 
     Model = new Model(); 
     Model.PropertyChanged += Model_PropertyChanged; 
    } 

    void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 
    { 

     System.Diagnostics.Debug.WriteLine(e.PropertyName); 

     if (PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs("ModelItemCollection")); 
     } 
    } 

    public ICommand AddCmd 
    { 
     get { return cmd ?? (cmd = new RelayCommand(a => Model.ModelItem.Add(new ModelItem {Name = "asd"}))); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

///---------------------- 

public class Model: INotifyPropertyChanged 
{ 
    public ObservableCollection<ModelItem> ModelItem { get; set; } 

    public Model() 
    { 
     ModelItem = new ObservableCollection<ModelItem>(); 
     ModelItem.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ModelItem_CollectionChanged); 
    } 

    void ModelItem_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     if (PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs("ModelItem")); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

public class ModelItem 
{ 
    public String Name { get; set; } 
} 

명시 적으로 PropertyChanged()를 호출해도 아무 것도 업데이트되지 않습니다.

ObservableCollection에 변경된 요소가 있음을 DependencyProperty에 알리는 해결 방법은 무엇입니까?

+0

나는 당신이 여기서보고있는 것은 ObservableCollection에의 사용으로 혼란 때문이라고 생각 . ObservableCollection 자체를 초기화 한 후에는 ObservableCollection 자체가 변경되지 않으므로 ObservableCollection 내에서 요소 *를 추가하거나 제거하려고하므로 속성 변경 이벤트가 표시되지 않습니다. 따라서 속성 (ObservableCollection)은 자체를 변경하지 않으며 이벤트를 발생시키지 않습니다. 그러나 ObservableCollection (ItemSource 또는 뭔가)에 바인딩하면 컬렉션에 항목을 추가하거나 제거 할 때 변경 사항을 가져와야합니다. 문제를 오해하니? – Kevek

+0

문제없이 항목을 추가하고 화면에 표시되는 것을 볼 수 있습니다. 내 문제는 DependencyProperty가 실행되지 않고 값이 설정되지 않는다는 사실에 관한 것입니다. 이것은 Model_PropertyChanged에서 명시 적으로 PropertyChanged (this, 새 PropertyChangedEventArgs ("ModelItemCollection"))를 추가하여 항목을 추가 할 때이 메서드 (Model_PropertyChanged)가 실행되었지만 여전히 : "다시 바인딩"하려는 ModelItemCollection을 필요로하는 이유입니다. –

+0

혹시 UpdateTarget()을 사용하려고 시도한 적이 있습니까? – Tigran

답변

1

의사 코드 : 여기

BindingOperations.GetBindingExpressionBase(dependencyObject, dependencyProperty).UpdateTarget(); 

봐 : forcing a WPF binding to 'refresh' ...

이 시도, 일반적으로 작동합니다 :)

+0

View t 모자 모델이 변경되었습니다. 이 호출은 객체 및 속성에 대한 참조가 필요하므로보기 측면에서만 수행 할 수 있습니다. –

+0

@Daok this는 * View *를 업데이트합니다. 이 호출은 새 정보를 가져 오기 위해 업데이트해야하는 소스 종속성 속성에 바인딩 된 모든 대상을 알립니다. – Kevek

+0

dependencyObject 및 dependencyProperty는 모두보기에 있습니다. 내 무지를 용서하지만 BindingOperations.GetBindingExpressionBase를 내가 액세스 할 수없는 두 가지로 호출 할 수 있습니까? (변경은 모델 측에서 수행됩니다)? –

관련 문제