2017-05-20 10 views
0

MVVMスタイルのプロジェクトで外部ライブラリから有用なユーザーコントロールモニタに興味がありました。 すべてはうまく見えますが、このコントロールには単純な(依存関係ではない)読み取り専用プロパティ(IList<ILogSource>)があります。 は少し考えた後、私はMonitorWrap他のコントロールと、このモニターコントロールをラップすることを決めた:依存プロパティ付きラッププロパティ

<UserControl 
    x:Class="Prj.CustomControls.MonitorWrap" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:catel="http://catel.codeplex.com" 
    xmlns:uc="clr-namespace:UsefulControll;assembly=UsefulControll"> 

    <uc:Monitor x:Name="Monitor" /> 
</UserControl> 

とコードで私は、依存関係プロパティを作成後ろ:

public partial class MonitorWrap : UserControl 
    { 
     /// <summary> 
     /// Initializes a new instance of the <see cref="MonitorWrap"/> class. 
     /// </summary> 
     public MonitorWrap() 
     { 
      InitializeComponent(); 

      DataContextChanged += (sender, args) => 
      { 
       //correct ViewModel sets to DataContext 
      }; 
     } 

     public IList<ILogSource> LogSources 
     { 
      get { return (IList<ILogSource>)GetValue(LogSourcesProperty); } 
      set { SetValue(LogSourcesProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty LogSourcesProperty = 
      DependencyProperty.Register("LogSources", typeof(IList<ILogSource>), typeof(MonitorWrap), new PropertyMetadata(null,ChangeCallback)); 

     private static void ChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var logControlPanelView = d as MonitorWrap; 

      //add elements from LogSources to readonly collection property. 
     } 
    } 

親XMLで次のステップ:

<customControls:MonitorWrap LogSources="{Binding Sources}"/> 

私は、変更はコールバックメソッドでは動作しません。

ので質問:

  1. 私は読み取り専用のコレクションを埋めるための正しい方法をつもり?
  2. どうしたの?なぜChangeCallbackメソッドが動作しません。

p.s. 私はMVVMフレームワークを使用しており、DataContextは正しく設定されています(MonitorWrapのラムダ式は正しく動作します)。

ViewModelにはあまりにも正常に動作

INotifyPropertyChangedとコード

protected override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e) 
     { 
      base.OnPropertyChanged(e); 
      if (e.PropertyName == "Sources") 
      { 
       //works fine on property changed 
      } 
     } 
を実装しています。

+0

したがって、Sourcesビューのモデルプロパティに項目を追加すると、ChangeCallbackを呼び出す必要があります。 – Clemens

+2

アイテムを追加するか、毎回完全に新しいコレクションをプッシュしますか? – Karolis

+0

いいえ。 'LogSources'が' null'(デフォルト)から 'typeof(Sources)'コレクションに値を変更したときに、 'ChangeCallback'の呼び出しを期待しています。 – risty

答えて

1

IList<ILogSource>あなたが得るよりも共分散のC#のサポートの詳細を求めるかもしれないように私は疑いように私に見えます。

viewmodelプロパティのタイプはIList<ILogSource>に割り当てる必要があり、そのルールはかなり厳しいものです。

基本的にObservableCollection<ILogSource>IList<ILogSource>ですが、IList<ILogSource_inherited_Class>ではありません。それはできないバインディングだけではありません。アイテムを一方から他方にコピーすることはできますが、キャストすることはできません。あなたがしたいのはコピーだけですが、型システムはそのことを知らないので、割り当てをしようとしているのが分かります。

タイプIEnumerable<ILogSource>see fiddle)の依存関係プロパティを作成するとうまくいくはずです。あなたがする必要があるのは、それから項目をコピーするだけで十分です。あなたが必要とするものがすべてIEnumerable<ILogSource>であれば、コンパイラにすべてが必要なものをIList<ILogSource>に伝えないでください。

関連する問題